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; 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) static int stbi__shiftsigned(int v, int shift, int bits)
{ {
int result; static unsigned int mul_table[9] = {
int z=0; 0,
0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/,
if (shift < 0) v <<= -shift; 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/,
else v >>= shift; };
result = v; static unsigned int shift_table[9] = {
0, 0,0,1,0,2,4,6,0,
z = bits; };
while (z < 8) { if (shift < 0)
result += v >> z; v <<= -shift;
z += bits; else
} v >>= shift;
return result; 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 typedef struct