Skip to content

Instantly share code, notes, and snippets.

@kusma
Created November 6, 2012 01:41
Show Gist options
  • Save kusma/4021937 to your computer and use it in GitHub Desktop.
Save kusma/4021937 to your computer and use it in GitHub Desktop.
Attempt on branch-free sRGB conversion by LUT without excessive range
#include <stdio.h>
#include <math.h>
#define LUT_LOG2_SIZE 8
#define LUT_SIZE ((1 << LUT_LOG2_SIZE) + 1)
float lut[LUT_SIZE];
float convert(float f)
{
union {
float f;
unsigned int i;
} u = { f };
/* perform max(f, 0) */
unsigned int mask = ~((signed int)u.i >> 31);
u.i &= mask;
/* bring 0..1.0 range to a fixed exponent */
u.f += 1.0f;
/* clear everything if greater than 1.0 */
mask = -((u.i >> 23) == 127);
u.i &= mask;
/* remote non-mantissa bits */
int idx = u.i & ((1 << 23) - 1);
/* set implicit 1 bit, so 1.0 doesn't become 0.0 */
idx |= ~mask & (1 << 23);
return lut[idx >> (23 - LUT_LOG2_SIZE)];
}
int main(int argc, char* argv[])
{
int i;
float f;
for (i = 0; i < LUT_SIZE; ++i) {
f = i * (1.0f / (LUT_SIZE - 1));
lut[i] = pow(f, 2.2f);
}
for (f = -1.0f; f < 2.0f; f += 0.2)
printf("%f\n", convert(f));
for (f = 2.0f; f < 4.0f; f += 0.4)
printf("%f\n", convert(f));
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment