Skip to content

Instantly share code, notes, and snippets.

@DJm00n
Last active November 21, 2023 21:39
Show Gist options
  • Save DJm00n/d289d318d549f0f9138fc9b95406bba7 to your computer and use it in GitHub Desktop.
Save DJm00n/d289d318d549f0f9138fc9b95406bba7 to your computer and use it in GitHub Desktop.
/**************************************************************************\
*
* Function Description:
*
* Convert a 32bpp premultiplied ARGB value to
* a 32bpp non-premultiplied ARGB value
*
* Arguments:
*
* argb - Premultiplied ARGB value
*
* Return Value:
*
* Non-premultiplied ARGB value
*
\**************************************************************************/
// Precomputed table for 255/a, 0 < a <= 255
// in 16.16 fixed point format
static const ARGB UnpremultiplyTable[256] =
{
0x000000,0xff0000,0x7f8000,0x550000,0x3fc000,0x330000,0x2a8000,0x246db6,
0x1fe000,0x1c5555,0x198000,0x172e8b,0x154000,0x139d89,0x1236db,0x110000,
0x0ff000,0x0f0000,0x0e2aaa,0x0d6bca,0x0cc000,0x0c2492,0x0b9745,0x0b1642,
0x0aa000,0x0a3333,0x09cec4,0x0971c7,0x091b6d,0x08cb08,0x088000,0x0839ce,
0x07f800,0x07ba2e,0x078000,0x074924,0x071555,0x06e453,0x06b5e5,0x0689d8,
0x066000,0x063831,0x061249,0x05ee23,0x05cba2,0x05aaaa,0x058b21,0x056cef,
0x055000,0x05343e,0x051999,0x050000,0x04e762,0x04cfb2,0x04b8e3,0x04a2e8,
0x048db6,0x047943,0x046584,0x045270,0x044000,0x042e29,0x041ce7,0x040c30,
0x03fc00,0x03ec4e,0x03dd17,0x03ce54,0x03c000,0x03b216,0x03a492,0x03976f,
0x038aaa,0x037e3f,0x037229,0x036666,0x035af2,0x034fca,0x0344ec,0x033a54,
0x033000,0x0325ed,0x031c18,0x031281,0x030924,0x030000,0x02f711,0x02ee58,
0x02e5d1,0x02dd7b,0x02d555,0x02cd5c,0x02c590,0x02bdef,0x02b677,0x02af28,
0x02a800,0x02a0fd,0x029a1f,0x029364,0x028ccc,0x028656,0x028000,0x0279c9,
0x0273b1,0x026db6,0x0267d9,0x026217,0x025c71,0x0256e6,0x025174,0x024c1b,
0x0246db,0x0241b2,0x023ca1,0x0237a6,0x0232c2,0x022df2,0x022938,0x022492,
0x022000,0x021b81,0x021714,0x0212bb,0x020e73,0x020a3d,0x020618,0x020204,
0x01fe00,0x01fa0b,0x01f627,0x01f252,0x01ee8b,0x01ead3,0x01e72a,0x01e38e,
0x01e000,0x01dc7f,0x01d90b,0x01d5a3,0x01d249,0x01cefa,0x01cbb7,0x01c880,
0x01c555,0x01c234,0x01bf1f,0x01bc14,0x01b914,0x01b61e,0x01b333,0x01b051,
0x01ad79,0x01aaaa,0x01a7e5,0x01a529,0x01a276,0x019fcb,0x019d2a,0x019a90,
0x019800,0x019577,0x0192f6,0x01907d,0x018e0c,0x018ba2,0x018940,0x0186e5,
0x018492,0x018245,0x018000,0x017dc1,0x017b88,0x017957,0x01772c,0x017507,
0x0172e8,0x0170d0,0x016ebd,0x016cb1,0x016aaa,0x0168a9,0x0166ae,0x0164b8,
0x0162c8,0x0160dd,0x015ef7,0x015d17,0x015b3b,0x015965,0x015794,0x0155c7,
0x015400,0x01523d,0x01507e,0x014ec4,0x014d0f,0x014b5e,0x0149b2,0x01480a,
0x014666,0x0144c6,0x01432b,0x014193,0x014000,0x013e70,0x013ce4,0x013b5c,
0x0139d8,0x013858,0x0136db,0x013562,0x0133ec,0x01327a,0x01310b,0x012fa0,
0x012e38,0x012cd4,0x012b73,0x012a15,0x0128ba,0x012762,0x01260d,0x0124bc,
0x01236d,0x012222,0x0120d9,0x011f93,0x011e50,0x011d10,0x011bd3,0x011a98,
0x011961,0x01182b,0x0116f9,0x0115c9,0x01149c,0x011371,0x011249,0x011123,
0x011000,0x010edf,0x010dc0,0x010ca4,0x010b8a,0x010a72,0x01095d,0x01084a,
0x010739,0x01062b,0x01051e,0x010414,0x01030c,0x010206,0x010102,0x010000,
};
#define ALPHA_SHIFT 24
#define RED_SHIFT 16
#define GREEN_SHIFT 8
#define BLUE_SHIFT 0
#define ALPHA_MASK ((ARGB) 0xff << ALPHA_SHIFT)
#define MAKEARGB(a, r, g, b) \
(((ARGB) ((a) & 0xff) << ALPHA_SHIFT) | \
((ARGB) ((r) & 0xff) << RED_SHIFT) | \
((ARGB) ((g) & 0xff) << GREEN_SHIFT) | \
((ARGB) ((b) & 0xff) << BLUE_SHIFT))
ARGB
Unpremultiply(
ARGB argb
)
{
// Get alpha value
ARGB a = argb >> ALPHA_SHIFT;
// Special case: fully transparent or fully opaque
if (a == 0 || a == 255)
return argb;
ARGB f = UnpremultiplyTable[a];
ARGB r = ((argb >> RED_SHIFT) & 0xff) * f >> 16;
ARGB g = ((argb >> GREEN_SHIFT) & 0xff) * f >> 16;
ARGB b = ((argb >> BLUE_SHIFT) & 0xff) * f >> 16;
return (a << ALPHA_SHIFT) |
((r > 255 ? 255 : r) << RED_SHIFT) |
((g > 255 ? 255 : g) << GREEN_SHIFT) |
((b > 255 ? 255 : b) << BLUE_SHIFT);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment