rewrite stbi__shiftsigned to use a different, faster algorithm

to avoid probelm with clang -O2 to outputting buggy code
This commit is contained in:
Sean Barrett 2018-01-29 02:30:34 -08:00
parent 68f857727c
commit 593c9b7192

View File

@ -4963,21 +4963,27 @@ static int stbi__bitcount(unsigned int a)
return a & 0xff;
}
// extract an arbitrarily-aligned N-bit value (N=bits)
// from v, and then make it 8-bits long and fractionally
// extend it to full full range.
static int stbi__shiftsigned(int v, int shift, int bits)
{
int result;
int z=0;
if (shift < 0) v <<= -shift;
else v >>= shift;
result = v;
z = bits;
while (z < 8) {
result += v >> z;
z += bits;
}
return result;
static unsigned int mul_table[9] = {
0,
0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/,
0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/,
};
static unsigned int shift_table[9] = {
0, 0,0,1,0,2,4,6,0,
};
if (shift < 0)
v <<= -shift;
else
v >>= shift;
assert(v >= 0 && v < 256);
v >>= (8-bits);
assert(bits >= 0 && bits <= 8);
return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
}
typedef struct