Leaked source code of windows server 2003
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.
 
 
 
 
 
 

140 lines
4.7 KiB

/**************************************************************************\
*
* Copyright (c) 1999-2000 Microsoft Corporation
*
* Module name:
*
* sRGB <-> sRGB64 color conversion
*
* Abstract:
*
* Converts colors between the sRGB and sRGB64 color spaces.
*
* Notes:
*
* !!![agodfrey]
* For sRGB64->sRGB, we just clamp out-of-range components to [0,255].
* We may need to provide the option of doing something more sophisticated.
*
* Revision History:
*
* 06/09/1999 agodfrey
* Created it.
*
\**************************************************************************/
#include "precomp.hpp"
namespace sRGB
{
BYTE UnlinLookup(INT16 input);
}
// UnlinearizeLUT, UnlinearizeLUT2: Lookup tables used to convert from
// sRGB64 to sRGB.
//
// The first table maps the high byte of the input to the smallest possible
// corresponding output.
//
// The second table describes, for each output, the maximum input which
// produces that output. The algorithm uses the first table to find an
// approximate answer, then scans the second table to find the exact result.
static BYTE UnlinearizeLUT[32] =
{
0x0, 0x31, 0x47, 0x56, 0x63, 0x6e, 0x78, 0x81,
0x89, 0x91, 0x98, 0x9e, 0xa5, 0xab, 0xb1, 0xb6,
0xbc, 0xc1, 0xc6, 0xca, 0xcf, 0xd4, 0xd8, 0xdc,
0xe1, 0xe5, 0xe9, 0xed, 0xf0, 0xf4, 0xf8, 0xfb,
};
static INT16 UnlinearizeLUT2[256] =
{
0x1, 0x3, 0x6, 0x8, 0xb, 0xd, 0x10, 0x12,
0x15, 0x17, 0x1a, 0x1c, 0x1f, 0x22, 0x25, 0x28,
0x2c, 0x2f, 0x33, 0x37, 0x3b, 0x3f, 0x43, 0x48,
0x4d, 0x52, 0x57, 0x5c, 0x61, 0x67, 0x6d, 0x73,
0x79, 0x7f, 0x86, 0x8d, 0x94, 0x9b, 0xa2, 0xa9,
0xb1, 0xb9, 0xc1, 0xca, 0xd2, 0xdb, 0xe4, 0xed,
0xf6, 0x100, 0x10a, 0x114, 0x11e, 0x128, 0x133, 0x13e,
0x149, 0x154, 0x160, 0x16c, 0x178, 0x184, 0x190, 0x19d,
0x1aa, 0x1b7, 0x1c5, 0x1d2, 0x1e0, 0x1ee, 0x1fc, 0x20b,
0x21a, 0x229, 0x238, 0x248, 0x257, 0x268, 0x278, 0x288,
0x299, 0x2aa, 0x2bb, 0x2cd, 0x2df, 0x2f1, 0x303, 0x316,
0x328, 0x33b, 0x34f, 0x362, 0x376, 0x38a, 0x39f, 0x3b3,
0x3c8, 0x3dd, 0x3f3, 0x409, 0x41e, 0x435, 0x44b, 0x462,
0x479, 0x490, 0x4a8, 0x4c0, 0x4d8, 0x4f1, 0x509, 0x522,
0x53c, 0x555, 0x56f, 0x589, 0x5a3, 0x5be, 0x5d9, 0x5f4,
0x610, 0x62c, 0x648, 0x664, 0x681, 0x69e, 0x6bb, 0x6d9,
0x6f7, 0x715, 0x733, 0x752, 0x771, 0x791, 0x7b0, 0x7d0,
0x7f1, 0x811, 0x832, 0x853, 0x875, 0x896, 0x8b8, 0x8db,
0x8fe, 0x921, 0x944, 0x968, 0x98b, 0x9b0, 0x9d4, 0x9f9,
0xa1e, 0xa44, 0xa6a, 0xa90, 0xab6, 0xadd, 0xb04, 0xb2b,
0xb53, 0xb7b, 0xba4, 0xbcc, 0xbf5, 0xc1f, 0xc48, 0xc72,
0xc9c, 0xcc7, 0xcf2, 0xd1d, 0xd49, 0xd75, 0xda1, 0xdce,
0xdfb, 0xe28, 0xe55, 0xe83, 0xeb2, 0xee0, 0xf0f, 0xf3e,
0xf6e, 0xf9e, 0xfce, 0xfff, 0x1030, 0x1061, 0x1093, 0x10c5,
0x10f7, 0x1129, 0x115c, 0x1190, 0x11c3, 0x11f7, 0x122c, 0x1261,
0x1296, 0x12cb, 0x1301, 0x1337, 0x136d, 0x13a4, 0x13db, 0x1413,
0x144b, 0x1483, 0x14bb, 0x14f4, 0x152e, 0x1567, 0x15a1, 0x15dc,
0x1616, 0x1651, 0x168d, 0x16c8, 0x1705, 0x1741, 0x177e, 0x17bb,
0x17f9, 0x1837, 0x1875, 0x18b4, 0x18f3, 0x1932, 0x1972, 0x19b2,
0x19f2, 0x1a33, 0x1a74, 0x1ab6, 0x1af8, 0x1b3a, 0x1b7d, 0x1bc0,
0x1c04, 0x1c47, 0x1c8c, 0x1cd0, 0x1d15, 0x1d5a, 0x1da0, 0x1de6,
0x1e2c, 0x1e73, 0x1eba, 0x1f02, 0x1f4a, 0x1f92, 0x1fdb, 0x7fff,
};
// Method of unlinearizing using a lookup table
//
// This has two steps - first, we use the high byte of the input
// to get an approximate answer for the output (using UnlinearizeLUT).
//
// Then we scan UnlinearizeLUT2 to find the exact answer.
// The i'th entry of UnlinearizeLUT2 is the highest input which will map
// to i.
BYTE
sRGB::UnlinLookup(
INT16 input
)
{
BYTE temp = UnlinearizeLUT[(input & 0xff00)>>8];
INT16 *lutPtr = &UnlinearizeLUT2[temp];
while (*lutPtr < input)
{
temp++;
lutPtr++;
}
return temp;
}
// CLAMP64: Map inputs below 0 to 0, above SRGB_ONE to 255,
// and in between to the given expression.
#define CLAMP64(input, expr) (((input) <= 0) ? 0 : \
(((input) >= SRGB_ONE) ? 255 : \
(expr)))
ARGB
sRGB::ConvertTosRGB(
ARGB64 color
)
{
sRGBColor result;
sRGB64Color c;
c.argb = color;
// [agodfrey] The compiler generates an IMUL for the multiply by 255,
// and I can't get it to use a MUL instead. Oh well, it's probably
// insignificant.
result.a = CLAMP64(c.a, (c.a * 255) >> SRGB_FRACTIONBITS);
result.r = CLAMP64(c.r, UnlinLookup(c.r));
result.g = CLAMP64(c.g, UnlinLookup(c.g));
result.b = CLAMP64(c.b, UnlinLookup(c.b));
return result.argb;
}