Code: Select all
#define RB(y,u,v) (((y)&0x3FF)<<22)|(((u)&0x3FF)<<11)|((v)&0x3FF)
#define GO(y,v) ((((y)+64)&0x3FF)<<22)|(16<<11)|(((v)+16)&0x3FF)
unsigned int DiffTable[128] = {
RB(-85, 160, 85), RB(-82, 155, 82), RB(-80, 150, 80), RB(-77, 145, 77),
RB(-74, 140, 74), RB(-72, 135, 72), RB(-69, 130, 69), RB(-66, 125, 66),
RB(-64, 120, 64), RB(-61, 115, 61), RB(-58, 110, 58), RB(-56, 105, 56),
RB(-53, 100, 53), RB(-50, 95, 50), RB(-48, 90, 48), RB(-45, 85, 45),
RB(-42, 80, 42), RB(-40, 75, 40), RB(-37, 70, 37), RB(-34, 65, 34),
RB(-32, 60, 32), RB(-29, 55, 29), RB(-26, 50, 24), RB(-24, 45, 22),
RB(-21, 40, 19), RB(-18, 35, 17), RB(-16, 30, 15), RB(-13, 25, 12),
RB(-10, 20, 10), RB( -8, 15, 7), RB( -5, 10, 5), RB( -2, 5, 2),
RB( 0, 0, 0), RB( 2, -5, -2), RB( 5, -10, -5), RB( 8, -15, -8),
RB( 10, -20, -10), RB( 13, -25, -13), RB( 16, -30, -15), RB( 18, -35, -17),
RB( 21, -40, -20), RB( 24, -45, -23), RB( 26, -50, -25), RB( 29, -55, -29),
RB( 32, -60, -32), RB( 34, -65, -34), RB( 37, -70, -37), RB( 40, -75, -40),
RB( 42, -80, -42), RB( 45, -85, -45), RB( 48, -90, -48), RB( 50, -95, -50),
RB( 53,-100, -53), RB( 56,-105, -56), RB( 58,-110, -58), RB( 61,-115, -61),
RB( 64,-120, -64), RB( 66,-125, -66), RB( 69,-130, -69), RB( 72,-135, -72),
RB( 74,-140, -74), RB( 77,-145, -77), RB( 80,-150, -80), RB( 82,-155, -82),
GO(-85, -160), GO(-82, -155), GO(-80, -150), GO(-77, -145),
GO(-74, -140), GO(-72, -135), GO(-69, -130), GO(-66, -125),
GO(-64, -120), GO(-61, -115), GO(-58, -110), GO(-56, -105),
GO(-53, -100), GO(-50, -95), GO(-48, -90), GO(-45, -85),
GO(-42, -80), GO(-40, -75), GO(-37, -70), GO(-34, -65),
GO(-32, -60), GO(-29, -55), GO(-26, -50), GO(-24, -45),
GO(-21, -40), GO(-18, -35), GO(-16, -30), GO(-13, -25),
GO(-10, -20), GO( -8, -15), GO( -5, -10), GO( -2, -5),
GO( 0, 0), GO( 2, 5), GO( 5, 10), GO( 8, 15),
GO( 10, 19), GO( 13, 25), GO( 15, 30), GO( 18, 35),
GO( 21, 40), GO( 23, 45), GO( 26, 49), GO( 29, 55),
GO( 32, 60), GO( 34, 65), GO( 37, 70), GO( 40, 75),
GO( 42, 80), GO( 45, 85), GO( 48, 90), GO( 50, 95),
GO( 53, 100), GO( 56, 105), GO( 58, 110), GO( 61, 115),
GO( 64, 120), GO( 66, 125), GO( 69, 130), GO( 72, 135),
GO( 74, 140), GO( 77, 145), GO( 80, 150), GO( 82, 155),
};
unsigned int RGBUnpack(unsigned int x) {
return (x * 0x10001) & 0x03E07C1F;
}
/* Alternate construction skips the 0x8020 constant, but requires */
/* adc slot,0 before slot can be used each time. Possible to gain */
/* speed due to increased pairing possibilities on newer machines */
/* but almost impossible to represent in C code. */
/* This is possible because MOVZX/MOVSX don't affect any flags, & */
/* the >>= punts the last bit into the carry slot. Very unobvious */
/* optimization, and one of the few that still applies on the new */
/* CPU's unlike the convoluted AA-related stuff of yore. */
int ExpandedDiff(unsigned int c0, unsigned int c1) {
unsigned int diff, acum, slot;
/* Pentium */
diff = c0 ; /* U/p0 */
diff -= c1 ; /* U/p0 */
slot = (( signed char)diff); /* U/p0 */
diff += 0x8020 ; /* V/p1 */
diff >>= 10 ; /* U/p0 */
acum = DiffTable[slot + 32]; /* V/p2 */
slot = ((unsigned char)diff); /* U/p0 */
acum ^= (0x3FF << 11) ; /* V/p1 */
diff >>= 11 ; /* U/p0 */
acum += DiffTable[slot ]; /* V/p1+p2 */
slot = (( signed char)diff); /* U/p0 */
acum += DiffTable[slot + 96]; /* U/p0+p2 */
return acum & RB(-128,-32,-32); /* bitmask */
}