/**************************************************************************\ * * Copyright (c) 1999-2000 Microsoft Corporation * * Module Name: * * sRGB/sRGB64 conversion. * * Abstract: * * Conversion between the sRGB and sRGB64 color spaces. * * Created: * * 6/9/1999 agodfrey * \**************************************************************************/ #ifndef _SRGB_HPP #define _SRGB_HPP // We cast ARGB and ARGB64 variables to these unions when necessary. // We could instead define ARGB and ARGB64 to be unions themselves, but the // compiler is bad at enregistering unions. namespace sRGB { // LinearizeLUT: Lookup table used to convert from sRGB to sRGB64 static DWORD LinearizeLUT[256] = { 0x0, 0x2, 0x5, 0x7, 0xa, 0xc, 0xf, 0x11, 0x14, 0x16, 0x19, 0x1b, 0x1e, 0x21, 0x24, 0x27, 0x2a, 0x2e, 0x32, 0x35, 0x39, 0x3d, 0x42, 0x46, 0x4b, 0x50, 0x55, 0x5a, 0x5f, 0x65, 0x6a, 0x70, 0x76, 0x7d, 0x83, 0x8a, 0x91, 0x98, 0x9f, 0xa6, 0xae, 0xb6, 0xbe, 0xc6, 0xce, 0xd7, 0xe0, 0xe9, 0xf2, 0xfc, 0x105, 0x10f, 0x119, 0x124, 0x12e, 0x139, 0x144, 0x14f, 0x15b, 0x166, 0x172, 0x17e, 0x18b, 0x197, 0x1a4, 0x1b1, 0x1be, 0x1cc, 0x1da, 0x1e8, 0x1f6, 0x204, 0x213, 0x222, 0x231, 0x240, 0x250, 0x260, 0x270, 0x281, 0x291, 0x2a2, 0x2b3, 0x2c5, 0x2d6, 0x2e8, 0x2fa, 0x30d, 0x31f, 0x332, 0x346, 0x359, 0x36d, 0x381, 0x395, 0x3a9, 0x3be, 0x3d3, 0x3e9, 0x3fe, 0x414, 0x42a, 0x440, 0x457, 0x46e, 0x485, 0x49d, 0x4b4, 0x4cc, 0x4e5, 0x4fd, 0x516, 0x52f, 0x549, 0x562, 0x57c, 0x597, 0x5b1, 0x5cc, 0x5e7, 0x603, 0x61e, 0x63a, 0x657, 0x673, 0x690, 0x6ad, 0x6cb, 0x6e8, 0x706, 0x725, 0x743, 0x762, 0x781, 0x7a1, 0x7c1, 0x7e1, 0x801, 0x822, 0x843, 0x864, 0x886, 0x8a8, 0x8ca, 0x8ed, 0x910, 0x933, 0x956, 0x97a, 0x99e, 0x9c2, 0x9e7, 0xa0c, 0xa32, 0xa57, 0xa7d, 0xaa3, 0xaca, 0xaf1, 0xb18, 0xb40, 0xb68, 0xb90, 0xbb8, 0xbe1, 0xc0a, 0xc34, 0xc5e, 0xc88, 0xcb2, 0xcdd, 0xd08, 0xd34, 0xd5f, 0xd8b, 0xdb8, 0xde5, 0xe12, 0xe3f, 0xe6d, 0xe9b, 0xec9, 0xef8, 0xf27, 0xf57, 0xf86, 0xfb6, 0xfe7, 0x1018, 0x1049, 0x107a, 0x10ac, 0x10de, 0x1111, 0x1143, 0x1177, 0x11aa, 0x11de, 0x1212, 0x1247, 0x127c, 0x12b1, 0x12e6, 0x131c, 0x1353, 0x1389, 0x13c0, 0x13f7, 0x142f, 0x1467, 0x14a0, 0x14d8, 0x1511, 0x154b, 0x1585, 0x15bf, 0x15f9, 0x1634, 0x166f, 0x16ab, 0x16e7, 0x1723, 0x1760, 0x179d, 0x17da, 0x1818, 0x1856, 0x1895, 0x18d4, 0x1913, 0x1952, 0x1992, 0x19d3, 0x1a13, 0x1a54, 0x1a96, 0x1ad7, 0x1b1a, 0x1b5c, 0x1b9f, 0x1be2, 0x1c26, 0x1c6a, 0x1cae, 0x1cf3, 0x1d38, 0x1d7e, 0x1dc3, 0x1e0a, 0x1e50, 0x1e97, 0x1edf, 0x1f26, 0x1f6f, 0x1fb7, 0x2000, }; // Lookup table to convert alpha to sRGB64, which is: // LinearizeAlphaLUT[i]=i*SRGB_ONE/255; static DWORD LinearizeAlphaLUT[256]= { 0x0000, 0x0020, 0x0040, 0x0060, 0x0080, 0x00A0, 0x00C0, 0x00E0, 0x0101, 0x0121, 0x0141, 0x0161, 0x0181, 0x01A1, 0x01C1, 0x01E1, 0x0202, 0x0222, 0x0242, 0x0262, 0x0282, 0x02A2, 0x02C2, 0x02E2, 0x0303, 0x0323, 0x0343, 0x0363, 0x0383, 0x03A3, 0x03C3, 0x03E3, 0x0404, 0x0424, 0x0444, 0x0464, 0x0484, 0x04A4, 0x04C4, 0x04E4, 0x0505, 0x0525, 0x0545, 0x0565, 0x0585, 0x05A5, 0x05C5, 0x05E5, 0x0606, 0x0626, 0x0646, 0x0666, 0x0686, 0x06A6, 0x06C6, 0x06E6, 0x0707, 0x0727, 0x0747, 0x0767, 0x0787, 0x07A7, 0x07C7, 0x07E7, 0x0808, 0x0828, 0x0848, 0x0868, 0x0888, 0x08A8, 0x08C8, 0x08E8, 0x0909, 0x0929, 0x0949, 0x0969, 0x0989, 0x09A9, 0x09C9, 0x09E9, 0x0A0A, 0x0A2A, 0x0A4A, 0x0A6A, 0x0A8A, 0x0AAA, 0x0ACA, 0x0AEA, 0x0B0B, 0x0B2B, 0x0B4B, 0x0B6B, 0x0B8B, 0x0BAB, 0x0BCB, 0x0BEB, 0x0C0C, 0x0C2C, 0x0C4C, 0x0C6C, 0x0C8C, 0x0CAC, 0x0CCC, 0x0CEC, 0x0D0D, 0x0D2D, 0x0D4D, 0x0D6D, 0x0D8D, 0x0DAD, 0x0DCD, 0x0DED, 0x0E0E, 0x0E2E, 0x0E4E, 0x0E6E, 0x0E8E, 0x0EAE, 0x0ECE, 0x0EEE, 0x0F0F, 0x0F2F, 0x0F4F, 0x0F6F, 0x0F8F, 0x0FAF, 0x0FCF, 0x0FEF, 0x1010, 0x1030, 0x1050, 0x1070, 0x1090, 0x10B0, 0x10D0, 0x10F0, 0x1111, 0x1131, 0x1151, 0x1171, 0x1191, 0x11B1, 0x11D1, 0x11F1, 0x1212, 0x1232, 0x1252, 0x1272, 0x1292, 0x12B2, 0x12D2, 0x12F2, 0x1313, 0x1333, 0x1353, 0x1373, 0x1393, 0x13B3, 0x13D3, 0x13F3, 0x1414, 0x1434, 0x1454, 0x1474, 0x1494, 0x14B4, 0x14D4, 0x14F4, 0x1515, 0x1535, 0x1555, 0x1575, 0x1595, 0x15B5, 0x15D5, 0x15F5, 0x1616, 0x1636, 0x1656, 0x1676, 0x1696, 0x16B6, 0x16D6, 0x16F6, 0x1717, 0x1737, 0x1757, 0x1777, 0x1797, 0x17B7, 0x17D7, 0x17F7, 0x1818, 0x1838, 0x1858, 0x1878, 0x1898, 0x18B8, 0x18D8, 0x18F8, 0x1919, 0x1939, 0x1959, 0x1979, 0x1999, 0x19B9, 0x19D9, 0x19F9, 0x1A1A, 0x1A3A, 0x1A5A, 0x1A7A, 0x1A9A, 0x1ABA, 0x1ADA, 0x1AFA, 0x1B1B, 0x1B3B, 0x1B5B, 0x1B7B, 0x1B9B, 0x1BBB, 0x1BDB, 0x1BFB, 0x1C1C, 0x1C3C, 0x1C5C, 0x1C7C, 0x1C9C, 0x1CBC, 0x1CDC, 0x1CFC, 0x1D1D, 0x1D3D, 0x1D5D, 0x1D7D, 0x1D9D, 0x1DBD, 0x1DDD, 0x1DFD, 0x1E1E, 0x1E3E, 0x1E5E, 0x1E7E, 0x1E9E, 0x1EBE, 0x1EDE, 0x1EFE, 0x1F1F, 0x1F3F, 0x1F5F, 0x1F7F, 0x1F9F, 0x1FBF, 0x1FDF, 0x2000 }; union sRGBColor { struct { BYTE b, g, r, a; }; ARGB argb; }; #define SRGB_FRACTIONBITS 13 #define SRGB_INTEGERBITS (16-SRGB_FRACTIONBITS) #define SRGB_ONE (1<<(SRGB_FRACTIONBITS)) #define SRGB_HALF (1<<(SRGB_FRACTIONBITS-1)) union sRGB64Color { struct { INT16 b, g, r, a; }; ARGB64 argb; }; inline VOID ConvertTosRGB64(ARGB color,ARGB64 *result) { (*(DWORD*)result)=(LinearizeLUT[(DWORD)(color&0x0000ff00)>>8]<<16) | (LinearizeLUT[(DWORD)color&0x000000ff]); // GGBB (*((DWORD*)result+1))=(LinearizeAlphaLUT[(DWORD)color>>24]<<16) | (LinearizeLUT[(DWORD)(color&0x00ff0000)>>16]); // AARR } ARGB ConvertTosRGB(ARGB64 color); // isTranslucent* returns FALSE if the specified alpha value is either // completely transparent or completely opaque. // // NOTE: This method EXPECTS overflow on the alpha byte (a tricky // way to avoid an extra 'if') // Equivalent to: (alpha != 0) && (alpha != 255) inline BOOL isTranslucent(ARGB argb) { ASSERT((((ARGB)0)-1) > 0); // Make sure ARGB is an unsigned dword return ((argb>>24)-1 < 0xFE); } // Equivalent to: (alpha > 0) && (alpha < sRGB::SRGB_ONE) // !!![agodfrey] Revisit this when we know the meaning of // alpha > 1 and alpha < 0. inline BOOL isTranslucent64(INT16 alpha) { return (((UINT16) (alpha-1)) <= ((UINT16) SRGB_ONE)); } }; #endif