function HSLToRGB(h,s,l:word):longint;
{Hue, sat ve lum degerleri verilen rengin RGB degerlerini bulur}
var
	r,g,b,r1,r2,g1,g2,b1,b2,
	hy						: integer;

	procedure yukselt(var w:integer);
	begin
		if w = 0 then
			w:=w+round(255/120*(l-120));
	end;

	procedure azalt(var w:integer);
	begin
		if w = 255 then
			w:=w-round(255/120*(120-l));
	end;

begin
	{first the nearest value of H and H+40 for Hy,240,120 RGB values}
	{once en yakin H ve H+40 icin Hy,240,120'nin RGB degerleri:}
	hy:=(h div 40)*40;
	if hy in [0,40,200] then
		r1:=255
	else
		r1:=0;
	if hy in [40,80,120] then
		g1:=255
	else
		g1:=0;
	if hy in [120,160,200] then
		b1:=255
	else
		b1:=0;

	if hy in [200,0,160] then
		r2:=255
	else
		r2:=0;
	if hy in [0,40,80] then
		g2:=255
	else
		g2:=0;
	if hy in [80,120,160] then
		b2:=255
	else
		b2:=0;

	{then RGB values for Hy,240,L}
	{sonra Hy,240,L icin RGB degeri}
	if L > 120 then{255,255,255'e dogru segirtecekler}{they will tend to 255,255,255}
		begin
		yukselt(r1);
		yukselt(g1);
		yukselt(b1);
		yukselt(r2);
		yukselt(g2);
		yukselt(b2);
		end;{L > 120}
	if L < 120 then{0,0,0'a dogru degisecekler}{tend to 0,0,0}
		begin
		azalt(r1);
		azalt(g1);
		azalt(b1);
		azalt(r2);
		azalt(g2);
		azalt(b2);
		end;{L < 120}

	{and now one value for H,240,L; another value for H,0,L then find
  the RGB value of H,S,L}
	{simdi de H,240,L icin bir deger, H,0,L icin bir baska deger bulup
	buna gore H,S,L icin RGB'yi buluz edecegiz}
	r1:=r1+round((r2-r1)/40*(h mod 40));
	g1:=g1+round((g2-g1)/40*(h mod 40));
	b1:=b1+round((b2-b1)/40*(h mod 40));{Bunlar, H,240,L degerleri}
	r2:=round(l*1.0625);
	g2:=r2;
	b2:=r2;{Bunlar da H,0,L degerleri}{these are H,0,L values}
	r:=r1+round((r2-r1)/240*(240-s));
	g:=g1+round((g2-g1)/240*(240-s));
	b:=b1+round((b2-b1)/240*(240-s));
	HSLToRGB:=rgb(r,g,b);
end;

function RGBToHSL(r,g,b:word):longint;
{find the HSL values of the given color in format RGB, means that
RValue(result)=H, GValue(result)=S..}
{verilen RGB rengine karsilik gelen H,S,L'i, sanki R G B degerleriymis gibi
donderir. Yani RValue(..) = H, GValue(..)=S}
var
	dH,dH0,RR,GG,BB,BB0,BB1,k,s1,s2,l1,l2,CA,CB,CC,delta	: real;
	H,S,L,nr,ng,nb,KesinRenk												: integer;

	procedure HHesabi;
	begin
		dH:=dH0;
		case KesinRenk of
			0:
				begin
				if nr = 2 then
					if nb = 1 then
						H:=round(200+dH)
					else
						H:=round(40-dh);
				if ng = 2 then
					if nr = 1 then
						H:=round(40+dh)
					else
						H:=round(120-dh);
				if nb = 2 then
					if nr = 1 then
						 H:=round(200-dh)
					else
						H:=round(120+dh);
				end;{0}
			12:
				begin
				if nr = 0 then
					H:=120;
				if ng = 0 then
					H:=200;
				if nb = 0 then
					H:=40;
				end;{12}
			23:
				begin
				if nr = 2 then
					H:=0;
				if ng = 2 then
					H:=80;
				if nb = 2 then
					H:=160;
				end;{23}
			end;{case AyniRenk}
	end;

begin
{RR	: 1.renk
 BB	: 2.renk
 GG	: 3.renk
 BB1: 2.renk , ara deger}
	k:=1.0625;
	if (r = g) and (r = b) then
		begin
		H:=120;
		S:=0;
		L:=round(r/k);
		RGBToHSL:=rgb(H,S,L);
    {gray tone works...}
		{gri tonu isleri}
		exit;
		end;{r=g=b}
	nr:=0;
	ng:=0;
	nb:=0;
	if r >= g then
		inc(nr)
	else
		inc(ng);
	if r >=b then
		inc(nr)
	else
		inc(nb);
	if g >= b then
		inc(ng)
	else
		inc(nb);
	if nr = 2 then
		RR:=r;
	if ng = 2 then
		RR:=g;
	if nb = 2 then
		RR:=b;
	if nr = 1 then
		BB:=r;
	if ng = 1 then
		BB:=g;
	if nb = 1 then
		BB:=b;
	if nr = 0 then
		GG:=r;
	if ng = 0 then
		GG:=g;
	if nb = 0 then
		GG:=b;
	dH0:=40-(BB-GG)/(RR-GG)*40;
	dh:=dH0;
	KesinRenk:=0;
	BB0:=BB;
	if RR = BB then
		begin
		BB:=RR-0.0000001;{nasil kandirdim ama salagi...}{just to deceive him! To not divide by 0}
		Kesinrenk:=12;{yani ust iki renk ayni}{two colors are same}
		end;
	if BB = GG then
		begin
		BB:=(RR+GG)/2;{!!!! BU DA NE DEMEK OLUYOR? demeyin, cunku iki renk birbirine
		esit olunca, H hesaplandiktan sonra, ortadaki rengi nasil degistirirsen degistir,
		S ve L degismiyor da degismiyor. Tabii, ortadaki rengin diger iki rengi tasmamasi
		kaydiyla...}
    {don't be surprised! Because when the two  colors are equal, whatever the third color is,
    S and L values dont change.}
		KesinRenk:=23;{alt iki renk ayni}
		dH:=20;
		end;
  BB1:=255*(1-dH/40);
  {ilk olarak L < 120 icin hesap kitap}
  s1:=255*120*(RR-BB);
  s2:=120*k*BB-BB1*RR+255*RR/2;
  S:=round(s1/s2);
  l1:=240*RR;
  l2:=255+k*s;
  if l2 = 0 then
    L:=121
  else
    L:=round(l1/l2);
  if (s >= 0) and (s <= 240) and (L < 120) then
    begin
    HHesabi;
    RGBToHSL:=rgb(H,S,L);
    exit;
    end;
	CB:=240*k*BB-510*BB1+255*255-255*240*k-240*k*GG+2*BB1*GG;
	CC:=255*240*(BB-GG);
	if CB = 0 then
		begin
		RGBToHSL:=0;
		exit;
		end;{CB = 0}
	S:=round(-CC/CB);
	l1:=GG+k*S;
	l2:=255+k*S;
	L:=round(240*l1/l2);
	if L < 120 then
		begin
		RGBToHSL:=0;
		exit;
		end;{L < 120}
	HHesabi;
	RGBToHSL:=rgb(H,s,l);
end;



    Source: geocities.com/~franzglaser/tpsrc

               ( geocities.com/~franzglaser)