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

Windows Kernel

Development Platform:

Visual C++

  1. /*  COLOR2.C
  2. **
  3. **  Copyright (C) Microsoft, 1993, All Rights Reserved.
  4. **
  5. **
  6. **  History:
  7. **
  8. */
  9. #include <windows.h>
  10. #include "desk.h"
  11. #include "look.h"
  12. int H,L,S;                         /* Hue, Lightness, Saturation */
  13. #define  RANGE   240                 /* range of values for HLS scrollbars */
  14.                                      /* HLS-RGB conversions work best when
  15.                                         RANGE is divisible by 6 */
  16. #define  HLSMAX   RANGE
  17. #define  RGBMAX   255
  18. #define MIN(a, b) ((a) < (b) ? (a) : (b))
  19. /* Color conversion routines --
  20.    RGBtoHLS() takes a DWORD RGB value, translates it to HLS, and stores the
  21.    results in the global vars H, L, and S.  HLStoRGB takes the current values
  22.    of H, L, and S and returns the equivalent value in an RGB DWORD.  The vars
  23.    H, L and S are written to only by 1) RGBtoHLS (initialization) or 2) the
  24.    scrollbar handlers.
  25.    A point of reference for the algorithms is Foley and Van Dam, pp. 618-19.
  26.    Their algorithm is in floating point.  CHART implements a less general
  27.    (hardwired ranges) integral algorithm.
  28. */
  29. /* There are potential roundoff errors lurking throughout here.
  30.    (0.5 + x/y) without floating point,
  31.       (x/y) phrased ((x + (y/2))/y)
  32.    yields very small roundoff error.
  33.    This makes many of the following divisions look funny.
  34. */
  35.                         /* H,L, and S vary over 0-HLSMAX */
  36.                         /* R,G, and B vary over 0-RGBMAX */
  37.                         /* HLSMAX BEST IF DIVISIBLE BY 6 */
  38.                         /* RGBMAX, HLSMAX must each fit in a byte. */
  39. #define UNDEFINED (HLSMAX*2/3)/* Hue is undefined if Saturation is 0 (grey-scale) */
  40.                            /* This value determines where the Hue scrollbar is */
  41.                            /* initially set for achromatic colors */
  42. void   RGBtoHLS(DWORD lRGBColor)
  43. {
  44.    int R,G,B;                /* input RGB values */
  45.    WORD cMax,cMin;        /* max and min RGB values */
  46.    WORD cSum,cDif;
  47.    int  Rdelta,Gdelta,Bdelta;  /* intermediate value: % of spread from max */
  48.    /* get R, G, and B out of DWORD */
  49.    R = GetRValue(lRGBColor);
  50.    G = GetGValue(lRGBColor);
  51.    B = GetBValue(lRGBColor);
  52.    /* calculate lightness */
  53.    cMax = max( max(R,G), B);
  54.    cMin = min( min(R,G), B);
  55.    cSum = cMax + cMin;
  56.    L = (WORD)(((cSum * (DWORD)HLSMAX) + RGBMAX )/(2*RGBMAX));
  57.    cDif = cMax - cMin;
  58.    if (!cDif)    /* r=g=b --> achromatic case */
  59.      {
  60.        S = 0;                         /* saturation */
  61.        H = UNDEFINED;                 /* hue */
  62.      }
  63.    else                           /* chromatic case */
  64.      {
  65.        /* saturation */
  66.        if (L <= (HLSMAX/2))
  67.            S = (WORD) (((cDif * (DWORD) HLSMAX) + (cSum / 2) ) / cSum);
  68.        else
  69.            S = (WORD) ((DWORD) ((cDif * (DWORD) HLSMAX) + (DWORD)((2*RGBMAX-cSum)/2) )
  70.                                                  / (2*RGBMAX-cSum));
  71.       /* hue */
  72.       Rdelta = (int) (( ((cMax-R)*(DWORD)(HLSMAX/6)) + (cDif / 2) ) / cDif);
  73.       Gdelta = (int) (( ((cMax-G)*(DWORD)(HLSMAX/6)) + (cDif / 2) ) / cDif);
  74.       Bdelta = (int) (( ((cMax-B)*(DWORD)(HLSMAX/6)) + (cDif / 2) ) / cDif);
  75.       if ((WORD) R == cMax)
  76.          H = Bdelta - Gdelta;
  77.       else if ((WORD) G == cMax)
  78.          H = (HLSMAX/3) + Rdelta - Bdelta;
  79.       else /* B == cMax */
  80.          H = ((2*HLSMAX)/3) + Gdelta - Rdelta;
  81.       if (H < 0)
  82.          H += HLSMAX;
  83.       if (H > HLSMAX)
  84.          H -= HLSMAX;
  85.    }
  86. }
  87. /* utility routine for HLStoRGB */
  88. WORD NEAR PASCAL HueToRGB(WORD n1, WORD n2, WORD hue)
  89. {
  90.    /* range check: note values passed add/subtract thirds of range */
  91.    /* The following is redundant for WORD (unsigned int) */
  92. #if 0
  93.    if (hue < 0)
  94.       hue += HLSMAX;
  95. #endif
  96.    if (hue > HLSMAX)
  97.       hue -= HLSMAX;
  98.    /* return r,g, or b value from this tridrant */
  99.    if (hue < (HLSMAX/6))
  100.       return ( n1 + (((n2-n1)*hue+(HLSMAX/12))/(HLSMAX/6)) );
  101.    if (hue < (HLSMAX/2))
  102.       return ( n2 );
  103.    if (hue < ((HLSMAX*2)/3))
  104.       return ( n1 + (((n2-n1)*(((HLSMAX*2)/3)-hue)+(HLSMAX/12)) / (HLSMAX/6)) );
  105.    else
  106.       return ( n1 );
  107. }
  108. DWORD NEAR PASCAL HLStoRGB(WORD hue, WORD lum, WORD sat)
  109. {
  110.   WORD R,G,B;                      /* RGB component values */
  111.   WORD  Magic1,Magic2;       /* calculated magic numbers (really!) */
  112.   if (sat == 0)                /* achromatic case */
  113.     {
  114.       R = G = B = (lum * RGBMAX) / HLSMAX;
  115.       if (hue != UNDEFINED)
  116.         {
  117.          /* ERROR */
  118.         }
  119.     }
  120.   else                         /* chromatic case */
  121.     {
  122.       /* set up magic numbers */
  123.       if (lum <= (HLSMAX/2))
  124.           Magic2 = (WORD)((lum * ((DWORD)HLSMAX + sat) + (HLSMAX/2))/HLSMAX);
  125.       else
  126.           Magic2 = lum + sat - (WORD)(((lum*sat) + (DWORD)(HLSMAX/2))/HLSMAX);
  127.       Magic1 = 2*lum-Magic2;
  128.       /* get RGB, change units from HLSMAX to RGBMAX */
  129.       R = (WORD)((HueToRGB(Magic1,Magic2,(WORD)(hue+(WORD)(HLSMAX/3)))*(DWORD)RGBMAX + (HLSMAX/2))) / (WORD)HLSMAX;
  130.       G = (WORD)((HueToRGB(Magic1,Magic2,hue)*(DWORD)RGBMAX + (HLSMAX/2))) / HLSMAX;
  131.       B = (WORD)((HueToRGB(Magic1,Magic2,(WORD)(hue-(WORD)(HLSMAX/3)))*(DWORD)RGBMAX + (HLSMAX/2))) / (WORD)HLSMAX;
  132.     }
  133.   return(RGB(R,G,B));
  134. }
  135. DWORD  DarkenColor(DWORD rgb, int n)
  136. {
  137.     RGBtoHLS(rgb);
  138.     return HLStoRGB((WORD)H, (WORD)((long)L * n / 1000), (WORD)S);
  139. }
  140. DWORD  BrightenColor(DWORD rgb, int n)
  141. {
  142.     RGBtoHLS(rgb);
  143.     return HLStoRGB((WORD)H, (WORD)(((long)L * (1000-n) + (RANGE+1l)*n) / 1000), (WORD)S);
  144. }
  145. #ifdef OLDCODE
  146. void  Get3DColors(DWORD rgbFace, LPDWORD lprgbShadow, LPDWORD lprgbHilight)
  147. {
  148.     RGBtoHLS(rgbFace);
  149.     // colors are half way between the face and the min/max values
  150.     *lprgbShadow  = HLStoRGB(H, L * 2 / 3, S);
  151.     *lprgbHilight = HLStoRGB(H, (L + RANGE + 1) / 2, S);
  152.     *lprgbHilight = HLStoRGB(H, (L + RANGE + 1) / 2, S);
  153. //    *lprgbHilight = HLStoRGB(H, MIN(RANGE, L * 7 / 6), S);
  154. }
  155. #endif