Skip to content

Commit

Permalink
Guard some truncating casts with & 0xFF
Browse files Browse the repository at this point in the history
The result of adding two unsigned chars is an int, so assigning this again
to unsigned char results in a narrowing cast. Afaik this is well-defined
by the standard but code compiled with cl with all runtime checks enabled
will trigger a breakpoint when e.g. scanline[i] + recon[i - bytewidth]
yields a number > 255. Fix this, and make it clear what's happening, by
and'ing with 0xFF (which should be discarded by any sane optimizer anyway).
  • Loading branch information
stinos committed Aug 11, 2016
1 parent a71964e commit 4629cd6
Showing 1 changed file with 8 additions and 8 deletions.
16 changes: 8 additions & 8 deletions lodepng.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3980,12 +3980,12 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan
break;
case 1:
for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth];
for(i = bytewidth; i < length; ++i) recon[i] = (scanline[i] + recon[i - bytewidth]) & 0xFF;
break;
case 2:
if(precon)
{
for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i];
for(i = 0; i != length; ++i) recon[i] = (scanline[i] + precon[i]) & 0xFF;
}
else
{
Expand All @@ -3995,25 +3995,25 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan
case 3:
if(precon)
{
for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1);
for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1);
for(i = 0; i != bytewidth; ++i) recon[i] = (scanline[i] + (precon[i] >> 1)) & 0xFF;
for(i = bytewidth; i < length; ++i) recon[i] = (scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1)) & 0xFF;
}
else
{
for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1);
for(i = bytewidth; i < length; ++i) recon[i] = (scanline[i] + (recon[i - bytewidth] >> 1)) & 0xFF;
}
break;
case 4:
if(precon)
{
for(i = 0; i != bytewidth; ++i)
{
recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/
recon[i] = (scanline[i] + precon[i]) & 0xFF; /*paethPredictor(0, precon[i], 0) is always precon[i]*/
}
for(i = bytewidth; i < length; ++i)
{
recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])) & 0xFF;
}
}
else
Expand All @@ -4025,7 +4025,7 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan
for(i = bytewidth; i < length; ++i)
{
/*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/
recon[i] = (scanline[i] + recon[i - bytewidth]);
recon[i] = (scanline[i] + recon[i - bytewidth]) & 0xFF;
}
}
break;
Expand Down

0 comments on commit 4629cd6

Please sign in to comment.