You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
6.8 KiB
157 lines
6.8 KiB
/**************************************************************************\
|
|
*
|
|
* 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
|