ref: 19f4448a73daebe4a5218639839d5982ad1e7a44
parent: fe912350508c4d8a96db16c151df0af574a1e84f
author: rodri <rgl@antares-labs.eu>
date: Mon Feb 16 14:28:45 EST 2026
texture: use integers until the very end in memreadcolor()
--- a/color.c
+++ b/color.c
@@ -173,6 +173,30 @@
return c;
}
+ulong
+srgb2linearul(ulong c)
+{+ ulong l;
+
+ l = c & 0xff;
+ l |= srgb2lineartab[c>>8 & 0xff] << 8;
+ l |= srgb2lineartab[c>>16 & 0xff] << 16;
+ l |= srgb2lineartab[c>>24 & 0xff] << 24;
+ return l;
+}
+
+ulong
+linear2srgbul(ulong c)
+{+ ulong l;
+
+ l = c & 0xff;
+ l |= linear2srgbtab[c>>8 & 0xff] << 8;
+ l |= linear2srgbtab[c>>16 & 0xff] << 16;
+ l |= linear2srgbtab[c>>24 & 0xff] << 24;
+ return l;
+}
+
/* tone mapping */
--- a/graphics.h
+++ b/graphics.h
@@ -512,6 +512,8 @@
int hasalpha(ulong);
Color srgb2linear(Color);
Color linear2srgb(Color);
+ulong srgb2linearul(ulong);
+ulong linear2srgbul(ulong);
Color aces(Color);
Color aces2(Color);
--- a/texture.c
+++ b/texture.c
@@ -28,56 +28,59 @@
return Pt(uv.x*Dx(t->image->r), (1 - uv.y)*Dy(t->image->r));
}
-static Color
-cbuf2col(uchar b[4])
+#define divalpha1(a, v) ((((v)<<8)-(v))/(a))
+
+static ulong
+divalpha(ulong c)
{- Color c;
+ ushort r, g, b, a;
- c.a = b[0] / 255.0;
- c.b = b[1] / 255.0;
- c.g = b[2] / 255.0;
- c.r = b[3] / 255.0;
- return c;
+ a = c & 0xff;
+ b = c>>8 & 0xff;
+ g = c>>16 & 0xff;
+ r = c>>24 & 0xff;
+ r = divalpha1(a, r);
+ g = divalpha1(a, g);
+ b = divalpha1(a, b);
+ return (r<<24)|(g<<16)|(b<<8)|a;
}
static Color
memreadcolor(Texture *t, Point sp)
{- Color c;
- uchar cbuf[4];
+ union {+ uchar b[4];
+ ulong c;
+ } cbuf;
switch(t->image->chan){ default: sysfatal("unsupported texture format");case RGB24:
- unloadmemimage(t->image, rectaddpt(UR, sp), cbuf+1, sizeof cbuf - 1);
- cbuf[0] = 0xFF;
+ unloadmemimage(t->image, rectaddpt(UR, sp), cbuf.b+1, sizeof cbuf - 1);
+ cbuf.b[0] = 0xFF;
break;
case RGBA32:
- unloadmemimage(t->image, rectaddpt(UR, sp), cbuf, sizeof cbuf);
+ unloadmemimage(t->image, rectaddpt(UR, sp), cbuf.b, sizeof cbuf);
break;
case XRGB32:
- unloadmemimage(t->image, rectaddpt(UR, sp), cbuf, sizeof cbuf);
- memmove(cbuf+1, cbuf, 3);
- cbuf[0] = 0xFF;
+ unloadmemimage(t->image, rectaddpt(UR, sp), cbuf.b, sizeof cbuf);
+ memmove(cbuf.b+1, cbuf.b, 3);
+ cbuf.b[0] = 0xFF;
break;
case GREY8:
- unloadmemimage(t->image, rectaddpt(UR, sp), cbuf+1, 1);
- memset(cbuf+2, cbuf[1], 2);
- cbuf[0] = 0xFF;
+ unloadmemimage(t->image, rectaddpt(UR, sp), cbuf.b+1, 1);
+ memset(cbuf.b+2, cbuf.b[1], 2);
+ cbuf.b[0] = 0xFF;
break;
}
-
- c = cbuf2col(cbuf);
/* remove pre-multiplied alpha */
- if(hasalpha(t->image->chan) && c.a > 0 && c.a < 1){- c.r /= c.a;
- c.g /= c.a;
- c.b /= c.a;
- }
+ if(hasalpha(t->image->chan) && cbuf.b[0] != 0)
+ cbuf.c = divalpha(cbuf.c);
+
if(t->type == sRGBTexture)
- c = srgb2linear(c);
+ cbuf.c = srgb2linearul(cbuf.c);
- return c;
+ return ul2col(cbuf.c);
}
/*
--
⑨