mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
[libpng15] Added LSR() macro to defend against buggy compilers that evaluate
non-taken code branches and complain about out-of-range shifts.
This commit is contained in:
parent
b2068640d1
commit
ef02d563a3
7
ANNOUNCE
7
ANNOUNCE
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
Libpng 1.5.6rc02 - October 26, 2011
|
Libpng 1.5.6rc02 - October 27, 2011
|
||||||
|
|
||||||
This is not intended to be a public release. It will be replaced
|
This is not intended to be a public release. It will be replaced
|
||||||
within a few weeks by a public version or by another test version.
|
within a few weeks by a public version or by another test version.
|
||||||
@ -92,8 +92,9 @@ Version 1.5.6beta07 [October 21, 2011]
|
|||||||
Version 1.5.6rc01 [October 26, 2011]
|
Version 1.5.6rc01 [October 26, 2011]
|
||||||
Changed misleading "Missing PLTE before cHRM" warning to "Out of place cHRM"
|
Changed misleading "Missing PLTE before cHRM" warning to "Out of place cHRM"
|
||||||
|
|
||||||
Version 1.5.6rc02 [October 26, 2011]
|
Version 1.5.6rc02 [October 27, 2011]
|
||||||
|
Added LSR() macro to defend against buggy compilers that evaluate non-taken
|
||||||
|
code branches and complain about out-of-range shifts.
|
||||||
|
|
||||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net:
|
Send comments/corrections/commendations to png-mng-implement at lists.sf.net:
|
||||||
(subscription required; visit
|
(subscription required; visit
|
||||||
|
|||||||
4
CHANGES
4
CHANGES
@ -3653,7 +3653,9 @@ Version 1.5.6beta07 [October 21, 2011]
|
|||||||
Version 1.5.6rc01 [October 26, 2011]
|
Version 1.5.6rc01 [October 26, 2011]
|
||||||
Changed misleading "Missing PLTE before cHRM" warning to "Out of place cHRM"
|
Changed misleading "Missing PLTE before cHRM" warning to "Out of place cHRM"
|
||||||
|
|
||||||
Version 1.5.6rc02 [October 26, 2011]
|
Version 1.5.6rc02 [October 27, 2011]
|
||||||
|
Added LSR() macro to defend against buggy compilers that evaluate non-taken
|
||||||
|
code branches and complain about out-of-range shifts.
|
||||||
|
|
||||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||||
(subscription required; visit
|
(subscription required; visit
|
||||||
|
|||||||
74
pngrutil.c
74
pngrutil.c
@ -301,7 +301,7 @@ png_inflate(png_structp png_ptr, png_bytep data, png_size_t size,
|
|||||||
{
|
{
|
||||||
int ret, avail;
|
int ret, avail;
|
||||||
|
|
||||||
/* The setting of 'avail_in' used to be outside the loop, by setting it
|
/* The setting of 'avail_in' used to be outside the loop; by setting it
|
||||||
* inside it is possible to chunk the input to zlib and simply rely on
|
* inside it is possible to chunk the input to zlib and simply rely on
|
||||||
* zlib to advance the 'next_in' pointer. This allows arbitrary amounts o
|
* zlib to advance the 'next_in' pointer. This allows arbitrary amounts o
|
||||||
* data to be passed through zlib at the unavoidable cost of requiring a
|
* data to be passed through zlib at the unavoidable cost of requiring a
|
||||||
@ -2817,7 +2817,7 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
end_mask = (pixel_depth * row_width) & 7;
|
end_mask = (pixel_depth * row_width) & 7;
|
||||||
if (end_mask != 0)
|
if (end_mask != 0)
|
||||||
{
|
{
|
||||||
/* ep == NULL is a flag to say do nothing */
|
/* end_ptr == NULL is a flag to say do nothing */
|
||||||
end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
|
end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
|
||||||
end_byte = *end_ptr;
|
end_byte = *end_ptr;
|
||||||
# ifdef PNG_READ_PACKSWAP_SUPPORTED
|
# ifdef PNG_READ_PACKSWAP_SUPPORTED
|
||||||
@ -2830,9 +2830,11 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
/* end_mask is now the bits to *keep* from the destination row */
|
/* end_mask is now the bits to *keep* from the destination row */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This reduces to a memcpy for non-interlaced images and for the case where
|
/* For non-interlaced images this reduces to a png_memcpy(). A png_memcpy()
|
||||||
* interlacing isn't supported or isn't done (in that case the caller gets a
|
* will also happen if interlacing isn't supported or if the application
|
||||||
* sequence of interlace pass rows.)
|
* does not call png_set_interlace_handling(). In the latter cases the
|
||||||
|
* caller just gets a sequence of the unexpanded rows from each interlace
|
||||||
|
* pass.
|
||||||
*/
|
*/
|
||||||
#ifdef PNG_READ_INTERLACING_SUPPORTED
|
#ifdef PNG_READ_INTERLACING_SUPPORTED
|
||||||
if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) &&
|
if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) &&
|
||||||
@ -2848,9 +2850,9 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
|
|
||||||
if (pixel_depth < 8)
|
if (pixel_depth < 8)
|
||||||
{
|
{
|
||||||
/* For pixel depths up to 4bpp the 8-pixel mask can be expanded to fit
|
/* For pixel depths up to 4-bpp the 8-pixel mask can be expanded to fit
|
||||||
* into 32 bits, then a single loop over the bytes using the four byte
|
* into 32 bits, then a single loop over the bytes using the four byte
|
||||||
* values in the 32 bit mask can be used. For the 'display' option the
|
* values in the 32-bit mask can be used. For the 'display' option the
|
||||||
* expanded mask may also not require any masking within a byte. To
|
* expanded mask may also not require any masking within a byte. To
|
||||||
* make this work the PACKSWAP option must be taken into account - it
|
* make this work the PACKSWAP option must be taken into account - it
|
||||||
* simply requires the pixels to be reversed in each byte.
|
* simply requires the pixels to be reversed in each byte.
|
||||||
@ -2869,15 +2871,25 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
*
|
*
|
||||||
* The following defines allow generation of compile time constant bit
|
* The following defines allow generation of compile time constant bit
|
||||||
* masks for each pixel depth and each possibility of swapped or not
|
* masks for each pixel depth and each possibility of swapped or not
|
||||||
* swapped bytes. Pass is in the range 0..6, 'x', a pixel index, is in
|
* swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index,
|
||||||
* the range 0..7, the result is 1 if the pixel is to be copied in the
|
* is in the range 0..7; and the result is 1 if the pixel is to be
|
||||||
* pass, 0 if not. 'S' is for the sparkle method, 'B' for the block
|
* copied in the pass, 0 if not. 'S' is for the sparkle method, 'B'
|
||||||
* method.
|
* for the block method.
|
||||||
|
*
|
||||||
|
* With Microsoft Visual C and potentially other compilers the shifts
|
||||||
|
* below to extract the relevant fields from a 64 bit value are faulted
|
||||||
|
* if evaluated at compile time because the non-taken branch has an
|
||||||
|
* invalid shift (negative or more than 31), hence the following.
|
||||||
*/
|
*/
|
||||||
# define S_COPY(p,x) (((p)<4 ? 0x80088822 >> ((3-(p))*8+(7-(x))) :\
|
# if defined PNG_USE_COMPILE_TIME_MASKS && defined _MSC_VER
|
||||||
0xaa55ff00 >> ((7-(p))*8+(7-(x)))) & 1)
|
# define LSR(x,s) ((x)>>((s) & 0x1f))
|
||||||
# define B_COPY(p,x) (((p)<4 ? 0xff0fff33 >> ((3-(p))*8+(7-(x))) :\
|
# else
|
||||||
0xff55ff00 >> ((7-(p))*8+(7-(x)))) & 1)
|
# define LSR(x,s) ((x)>>(s))
|
||||||
|
# endif
|
||||||
|
# define S_COPY(p,x) (((p)<4 ? LSR(0x80088822,(3-(p))*8+(7-(x))) :\
|
||||||
|
LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1)
|
||||||
|
# define B_COPY(p,x) (((p)<4 ? LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\
|
||||||
|
LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1)
|
||||||
|
|
||||||
/* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is
|
/* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is
|
||||||
* little endian - the first pixel is at bit 0 - however the extra
|
* little endian - the first pixel is at bit 0 - however the extra
|
||||||
@ -2892,9 +2904,9 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
|
# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
|
||||||
# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
|
# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
|
||||||
|
|
||||||
/* Combine 8 of these to get the full mask. For the 1 and 2 bpp cases
|
/* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp
|
||||||
* the result needs replicating, for the 4bpp case the above generates
|
* cases the result needs replicating, for the 4-bpp case the above
|
||||||
* a full 32 bits.
|
* generates a full 32 bits.
|
||||||
*/
|
*/
|
||||||
# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))
|
# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))
|
||||||
|
|
||||||
@ -2972,7 +2984,7 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
png_uint_32 m;
|
png_uint_32 m;
|
||||||
|
|
||||||
/* It doesn't matter in the following if png_uint_32 has more than
|
/* It doesn't matter in the following if png_uint_32 has more than
|
||||||
* 32 bits because the high bits always match those in m<<24, it is,
|
* 32 bits because the high bits always match those in m<<24; it is,
|
||||||
* however, essential to use OR here, not +, because of this.
|
* however, essential to use OR here, not +, because of this.
|
||||||
*/
|
*/
|
||||||
m = mask;
|
m = mask;
|
||||||
@ -2988,7 +3000,7 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: this may overwrite the last byte with garbage if the image
|
/* NOTE: this may overwrite the last byte with garbage if the image
|
||||||
* is not an exact number of bytes wide, libpng has always done
|
* is not an exact number of bytes wide; libpng has always done
|
||||||
* this.
|
* this.
|
||||||
*/
|
*/
|
||||||
if (row_width <= pixels_per_byte)
|
if (row_width <= pixels_per_byte)
|
||||||
@ -3044,7 +3056,7 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;
|
bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;
|
||||||
|
|
||||||
/* And simply copy these bytes. Some optimization is possible here,
|
/* And simply copy these bytes. Some optimization is possible here,
|
||||||
* depending on the value of 'bytes_to_copy'. Speical case the low
|
* depending on the value of 'bytes_to_copy'. Special case the low
|
||||||
* byte counts, which we know to be frequent.
|
* byte counts, which we know to be frequent.
|
||||||
*
|
*
|
||||||
* Notice that these cases all 'return' rather than 'break' - this
|
* Notice that these cases all 'return' rather than 'break' - this
|
||||||
@ -3067,7 +3079,7 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
/* There is a possibility of a partial copy at the end here, this
|
/* There is a possibility of a partial copy at the end here; this
|
||||||
* slows the code down somewhat.
|
* slows the code down somewhat.
|
||||||
*/
|
*/
|
||||||
do
|
do
|
||||||
@ -3105,12 +3117,12 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE
|
#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE
|
||||||
/* Check for double byte alignment and, if possible, use a 16
|
/* Check for double byte alignment and, if possible, use a
|
||||||
* bit copy. Don't attempt this for narrow images - ones that
|
* 16-bit copy. Don't attempt this for narrow images - ones that
|
||||||
* are less than an interlace panel wide. Don't attempt it for
|
* are less than an interlace panel wide. Don't attempt it for
|
||||||
* wide bytes-to-copy either - use the memcpy there.
|
* wide bytes-to-copy either - use the png_memcpy there.
|
||||||
*/
|
*/
|
||||||
if (bytes_to_copy < 16 /*else use memcpy*/ &&
|
if (bytes_to_copy < 16 /*else use png_memcpy*/ &&
|
||||||
png_isaligned(dp, png_uint_16) &&
|
png_isaligned(dp, png_uint_16) &&
|
||||||
png_isaligned(sp, png_uint_16) &&
|
png_isaligned(sp, png_uint_16) &&
|
||||||
bytes_to_copy % sizeof (png_uint_16) == 0 &&
|
bytes_to_copy % sizeof (png_uint_16) == 0 &&
|
||||||
@ -3150,7 +3162,7 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
|
|
||||||
/* Get to here when the row_width truncates the final copy.
|
/* Get to here when the row_width truncates the final copy.
|
||||||
* There will be 1-3 bytes left to copy, so don't try the
|
* There will be 1-3 bytes left to copy, so don't try the
|
||||||
* 16bit loop below.
|
* 16-bit loop below.
|
||||||
*/
|
*/
|
||||||
dp = (png_bytep)dp32;
|
dp = (png_bytep)dp32;
|
||||||
sp = (png_const_bytep)sp32;
|
sp = (png_const_bytep)sp32;
|
||||||
@ -3160,7 +3172,7 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Else do it in 16 bit quantities, but only if the size is
|
/* Else do it in 16-bit quantities, but only if the size is
|
||||||
* not too large.
|
* not too large.
|
||||||
*/
|
*/
|
||||||
else
|
else
|
||||||
@ -3189,7 +3201,7 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
}
|
}
|
||||||
while (bytes_to_copy <= row_width);
|
while (bytes_to_copy <= row_width);
|
||||||
|
|
||||||
/* End of row - 1 byte left, bytes_to_copy>row_width: */
|
/* End of row - 1 byte left, bytes_to_copy > row_width: */
|
||||||
dp = (png_bytep)dp16;
|
dp = (png_bytep)dp16;
|
||||||
sp = (png_const_bytep)sp16;
|
sp = (png_const_bytep)sp16;
|
||||||
do
|
do
|
||||||
@ -3200,7 +3212,7 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
}
|
}
|
||||||
#endif /* PNG_ALIGN_ code */
|
#endif /* PNG_ALIGN_ code */
|
||||||
|
|
||||||
/* The true default - use a memcpy: */
|
/* The true default - use a png_memcpy: */
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
png_memcpy(dp, sp, bytes_to_copy);
|
png_memcpy(dp, sp, bytes_to_copy);
|
||||||
@ -3224,7 +3236,7 @@ png_combine_row(png_structp png_ptr, png_bytep dp, int display)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If here then the switch above wasn't used so just memcpy the whole row
|
/* If here then the switch above wasn't used so just png_memcpy the whole row
|
||||||
* from the temporary row buffer (notice that this overwrites the end of the
|
* from the temporary row buffer (notice that this overwrites the end of the
|
||||||
* destination row if it is a partial byte.)
|
* destination row if it is a partial byte.)
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user