color.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 6k
Category:

Windows Kernel

Development Platform:

Visual C++

  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. }