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.

186 lines
5.8 KiB

  1. #include "priv.h"
  2. // Copied mostly from Desk.cpl.
  3. #define RANGE 240 // range of values for HLS scrollbars
  4. // HLS-RGB conversions work best when
  5. // RANGE is divisible by 6
  6. #define HLSMAX RANGE
  7. #define RGBMAX 255
  8. #define UNDEFINED (HLSMAX*2/3) //Hue is undefined if Saturation is 0 (grey-scale)
  9. //-------------------------------------------------------------------------
  10. // ColorRGBToHLS
  11. //
  12. // Purpose: Convert RGB to HLS
  13. //
  14. // A point of reference for the algorithms is Foley and Van Dam, pp. 618-19.
  15. // Their algorithm is in floating point. CHART implements a less general
  16. // (hardwired ranges) integral algorithm.
  17. // There are potential roundoff errors lurking throughout here.
  18. // (0.5 + x/y) without floating point,
  19. // (x/y) phrased ((x + (y/2))/y)
  20. // yields very small roundoff error.
  21. // This makes many of the following divisions look funny.
  22. // H,L, and S vary over 0-HLSMAX
  23. // R,G, and B vary over 0-RGBMAX
  24. // HLSMAX BEST IF DIVISIBLE BY 6
  25. // RGBMAX, HLSMAX must each fit in a byte.
  26. STDAPI_(void) ColorRGBToHLS(COLORREF clrRGB, WORD* pwHue, WORD* pwLuminance, WORD* pwSaturation)
  27. {
  28. int R,G,B; /* input RGB values */
  29. WORD cMax,cMin; /* max and min RGB values */
  30. WORD cSum,cDif;
  31. int Rdelta,Gdelta,Bdelta; /* intermediate value: % of spread from max */
  32. int H, L, S;
  33. /* get R, G, and B out of DWORD */
  34. R = GetRValue(clrRGB);
  35. G = GetGValue(clrRGB);
  36. B = GetBValue(clrRGB);
  37. /* calculate lightness */
  38. cMax = max( max(R,G), B);
  39. cMin = min( min(R,G), B);
  40. cSum = cMax + cMin;
  41. L = (WORD)(((cSum * (DWORD)HLSMAX) + RGBMAX )/(2*RGBMAX));
  42. cDif = cMax - cMin;
  43. if (!cDif) /* r=g=b --> achromatic case */
  44. {
  45. S = 0; /* saturation */
  46. H = UNDEFINED; /* hue */
  47. }
  48. else /* chromatic case */
  49. {
  50. /* saturation */
  51. if (L <= (HLSMAX/2))
  52. S = (WORD) (((cDif * (DWORD) HLSMAX) + (cSum / 2) ) / cSum);
  53. else
  54. S = (WORD) ((DWORD) ((cDif * (DWORD) HLSMAX) + (DWORD)((2*RGBMAX-cSum)/2) )
  55. / (2*RGBMAX-cSum));
  56. /* hue */
  57. Rdelta = (int) (( ((cMax-R)*(DWORD)(HLSMAX/6)) + (cDif / 2) ) / cDif);
  58. Gdelta = (int) (( ((cMax-G)*(DWORD)(HLSMAX/6)) + (cDif / 2) ) / cDif);
  59. Bdelta = (int) (( ((cMax-B)*(DWORD)(HLSMAX/6)) + (cDif / 2) ) / cDif);
  60. if ((WORD) R == cMax)
  61. H = Bdelta - Gdelta;
  62. else if ((WORD) G == cMax)
  63. H = (HLSMAX/3) + Rdelta - Bdelta;
  64. else /* B == cMax */
  65. H = ((2*HLSMAX)/3) + Gdelta - Rdelta;
  66. if (H < 0)
  67. H += HLSMAX;
  68. if (H > HLSMAX)
  69. H -= HLSMAX;
  70. }
  71. ASSERT( pwHue && pwLuminance && pwSaturation );
  72. *pwHue = (WORD) H;
  73. *pwLuminance = (WORD) L;
  74. *pwSaturation = (WORD) S;
  75. }
  76. /* utility routine for HLStoRGB */
  77. WORD HueToRGB(WORD n1, WORD n2, WORD hue)
  78. {
  79. /* range check: note values passed add/subtract thirds of range */
  80. /* The following is redundant for WORD (unsigned int) */
  81. if (hue > HLSMAX)
  82. hue -= HLSMAX;
  83. /* return r,g, or b value from this tridrant */
  84. if (hue < (HLSMAX/6))
  85. return ( n1 + (((n2-n1)*hue+(HLSMAX/12))/(HLSMAX/6)) );
  86. if (hue < (HLSMAX/2))
  87. return ( n2 );
  88. if (hue < ((HLSMAX*2)/3))
  89. return ( n1 + (((n2-n1)*(((HLSMAX*2)/3)-hue)+(HLSMAX/12)) / (HLSMAX/6)) );
  90. else
  91. return ( n1 );
  92. }
  93. //-------------------------------------------------------------------------
  94. // ColorHLSToRGB
  95. //
  96. // Purpose: Convert HLS to RGB
  97. STDAPI_(COLORREF) ColorHLSToRGB(WORD wHue, WORD wLuminance, WORD wSaturation)
  98. {
  99. WORD R,G,B; /* RGB component values */
  100. WORD Magic1,Magic2; /* calculated magic numbers (really!) */
  101. if (wSaturation == 0) /* achromatic case */
  102. {
  103. R = G = B = (wLuminance * RGBMAX) / HLSMAX;
  104. if (wHue != UNDEFINED)
  105. {
  106. R = G = B = 0;
  107. }
  108. }
  109. else /* chromatic case */
  110. {
  111. /* set up magic numbers */
  112. if (wLuminance <= (HLSMAX/2))
  113. Magic2 = (WORD)((wLuminance * ((DWORD)HLSMAX + wSaturation) + (HLSMAX/2))/HLSMAX);
  114. else
  115. Magic2 = wLuminance + wSaturation - (WORD)(((wLuminance*wSaturation) + (DWORD)(HLSMAX/2))/HLSMAX);
  116. Magic1 = 2*wLuminance-Magic2;
  117. /* get RGB, change units from HLSMAX to RGBMAX */
  118. R = (WORD)((HueToRGB(Magic1,Magic2,(WORD)(wHue+(WORD)(HLSMAX/3)))*(DWORD)RGBMAX + (HLSMAX/2))) / (WORD)HLSMAX;
  119. G = (WORD)((HueToRGB(Magic1,Magic2,wHue)*(DWORD)RGBMAX + (HLSMAX/2))) / HLSMAX;
  120. B = (WORD)((HueToRGB(Magic1,Magic2,(WORD)(wHue-(WORD)(HLSMAX/3)))*(DWORD)RGBMAX + (HLSMAX/2))) / (WORD)HLSMAX;
  121. }
  122. return(RGB(R,G,B));
  123. }
  124. //-------------------------------------------------------------------------
  125. // ColorAdjustLuma
  126. //
  127. // Purpose: Adjusts the luma of an RGB value
  128. STDAPI_(COLORREF) ColorAdjustLuma(COLORREF clrRGB, int n, BOOL fScale)
  129. {
  130. WORD H, L, S;
  131. if (n == 0)
  132. return clrRGB;
  133. ColorRGBToHLS(clrRGB, &H, &L, &S);
  134. if (fScale)
  135. {
  136. if (n > 0)
  137. {
  138. return ColorHLSToRGB((WORD)H, (WORD)(((long)L * (1000 - n) + (RANGE + 1l) * n) / 1000), (WORD)S);
  139. }
  140. else
  141. {
  142. return ColorHLSToRGB((WORD)H, (WORD)(((long)L * (n + 1000)) / 1000), (WORD)S);
  143. }
  144. }
  145. L += (int)((long)n * RANGE / 1000);
  146. if (L < 0)
  147. L = 0;
  148. if (L > HLSMAX)
  149. L = HLSMAX;
  150. return ColorHLSToRGB((WORD)H, (WORD)L, (WORD)S);
  151. }