home *** CD-ROM | disk | FTP | other *** search
- // HLS.cpp: implementation of the CHLS class.
- //
- //////////////////////////////////////////////////////////////////////
-
- #include "stdafx.h"
- #include "HLS.h"
-
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
-
- CHLS::~CHLS()
- {
-
- }
-
- // default constructor (sets color to black)
- CHLS::CHLS():H(0),L(0),S(0){}
- CHLS::CHLS(unsigned short int h,unsigned short int l,unsigned short int s):H(h),L(l),S(s){} //constructor #2
-
- CHLS::CHLS(unsigned long int RGBColor)
- // This constructor is adapted from code from Microsoft Knowledge Base Article ID: Q29240
- {// begin RGBtoHLS constructor
- unsigned short int R,G,B; // input RGB values
- unsigned short int cMax,cMin; // max and min RGB values
- unsigned short int Rdelta,Gdelta,Bdelta; // intermediate value: % of spread from max
-
- // get R, G, and B out of DWORD
- R = GetRValue(RGBColor);
- G = GetGValue(RGBColor);
- B = GetBValue(RGBColor);
-
- // calculate lightness
- cMax = max( max(R,G), B);
- cMin = min( min(R,G), B);
- L = (unsigned short int)(( ((cMax+cMin)*HLSMAX) + RGBMAX )/(2*RGBMAX));
-
- if (cMax == cMin)
- { // r=g=b --> achromatic case
- S = 0; // saturation
- H = UNDEFINED; // hue
- }
- else
- { // chromatic case
- // saturation
- if (L <= (HLSMAX/2))
- S = (unsigned short int)(( ((cMax-cMin)*HLSMAX) + ((cMax+cMin)/2) ) / (cMax+cMin));
- else
- S = (unsigned short int)(( ((cMax-cMin)*HLSMAX) + ((2*RGBMAX-cMax-cMin)/2) )/ (2*RGBMAX-cMax-cMin));
-
- // hue
- Rdelta = (unsigned short int)(( ((cMax-R)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin));
- Gdelta = (unsigned short int)(( ((cMax-G)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin));
- Bdelta = (unsigned short int)(( ((cMax-B)*(HLSMAX/6)) + ((cMax-cMin)/2) ) / (cMax-cMin));
-
- if (R == cMax)
- H = (unsigned short int)(Bdelta - Gdelta);
- else if (G == cMax)
- H = (unsigned short int)((HLSMAX/3) + Rdelta - Bdelta);
- else // B == cMax
- H = (unsigned short int)(((2*HLSMAX)/3) + Gdelta - Rdelta);
-
- if (H < 0)
- H += HLSMAX;
- if (H > HLSMAX)
- H -= HLSMAX;
- }
- }// end RGBtoHLS constructor
-
- unsigned short int CHLS::HueToRGB(unsigned short int n1,unsigned short int n2,unsigned short int hue)
- // HueToRGB() is adapted from code from Microsoft Knowledge Base Article ID: Q29240
- {// begin HueToRGB
- // range check: note values passed add/subtract thirds of range
- if (hue < 0)
- hue += HLSMAX;
- if (hue > HLSMAX)
- hue -= HLSMAX;
-
- // return r,g, or b value from this tridrant
- if (hue < (HLSMAX/6))
- return (unsigned short int)(( n1 + (((n2-n1)*hue+(HLSMAX/12))/(HLSMAX/6)) ));
- if (hue < (HLSMAX/2))
- return (unsigned short int)( n2 );
- if (hue < ((HLSMAX*2)/3))
- return (unsigned short int)( n1 + (((n2-n1)*(((HLSMAX*2)/3)-hue)+(HLSMAX/12))/(HLSMAX/6)));
- else
- return (unsigned short int)( n1 );
- }// end HueToRGB
-
- unsigned long int CHLS::ToRGB()
- // ToRGB() is adapted from code from Microsoft Knowledge Base Article ID: Q29240
- {// begin ToRGB
- unsigned short int R,G,B; // RGB component values
- unsigned short int Magic1,Magic2; // calculated magic numbers (really!)
-
- if (S == 0)
- { // achromatic case
- R=G=B=(unsigned short int)((L*RGBMAX)/HLSMAX);
- if (H != UNDEFINED)
- {
- // ERROR
- }
- }
- else
- { // chromatic case
- // set up magic numbers
- if (L <= (HLSMAX/2))
- Magic2 = (unsigned short int)((L*(HLSMAX + S) + (HLSMAX/2))/HLSMAX);
- else
- Magic2 = (unsigned short int)(L + S - ((L*S) + (HLSMAX/2))/HLSMAX);
- Magic1 = (unsigned short int)(2*L-Magic2);
-
- // get RGB, change units from HLSMAX to RGBMAX
- R = (unsigned short int)((HueToRGB(Magic1,Magic2,H+(HLSMAX/3))*RGBMAX + (HLSMAX/2))/HLSMAX);
- G = (unsigned short int)((HueToRGB(Magic1,Magic2,H)*RGBMAX + (HLSMAX/2)) / HLSMAX);
- B = (unsigned short int)((HueToRGB(Magic1,Magic2,H-(HLSMAX/3))*RGBMAX + (HLSMAX/2))/HLSMAX);
- }
- return(RGB(R,G,B));
- }// end ToRGB