-- RGB - HSL -- -- 1. Convert the RBG values to the range 0-1 -- Example: from the video colors page, colorbar red has R=83%, B=7%, G=7%, or in this scale, -- R=.83, B=.07, G=.07 -- -- 2. Find min and max values of R, B, G -- In the example, maxcolor = .83, mincolor=.07 -- -- 3. L = (maxcolor + mincolor)/2 -- For the example, L = (.83+.07)/2 = .45 -- -- 4. If the max and min colors are the same (ie the color is some kind of grey), -- S is defined to be 0, and H is undefined but in programs usually written as 0 -- -- 5. Otherwise, test L. -- If L < 0.5, S=(maxcolor-mincolor)/(maxcolor+mincolor) -- If L >=0.5, S=(maxcolor-mincolor)/(2.0-maxcolor-mincolor) -- For the example, L=0.45 so S=(.83-.07)/(.83+.07) = .84 -- -- 6. If R=maxcolor, H = (G-B)/(maxcolor-mincolor) -- If G=maxcolor, H = 2.0 + (B-R)/(maxcolor-mincolor) -- If B=maxcolor, H = 4.0 + (R-G)/(maxcolor-mincolor) -- For the example, R=maxcolor so H = (.07-.07)/(.83-.07) = 0 -- -- 7. To use the scaling shown in the video color page, convert L and S back to percentages, -- and H into an angle in degrees (ie scale it from 0-360). From the computation in step 6, -- H will range from 0-6. RGB space is a cube, and HSL space is a double hexacone, -- where L is the principal diagonal of the RGB cube. -- Thus corners of the RGB cube; red, yellow, green, cyan, blue, and magenta, become the vertices -- of the HSL hexagon. Then the value 0-6 for H tells you which section of the hexgon you are in. -- H is most commonly given as in degrees, so to convert -- H = H*60.0 -- If H is negative, add 360 to complete the conversion. LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; USE ieee.std_logic_unsigned.all; ENTITY rgb_hsl IS PORT( R_in : IN STD_LOGIC_VECTOR(7 DOWNTO 0); V_in : IN STD_LOGIC_VECTOR(7 DOWNTO 0); B_in : IN STD_LOGIC_VECTOR(7 DOWNTO 0); H : OUT STD_LOGIC_VECTOR(10 DOWNTO 0); S : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); L : OUT STD_LOGIC_VECTOR(8 DOWNTO 0) ); END rgb_hsl; ARCHITECTURE a OF rgb_hsl IS SIGNAL maxcolor : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL mincolor : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL colorsum : STD_LOGIC_VECTOR(8 DOWNTO 0); SIGNAL colordif : STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL R_max : STD_LOGIC; SIGNAL V_max : STD_LOGIC; signal remain_sig : std_logic_vector(7 downto 0); signal quotient : std_logic_vector(15 downto 0); signal denom_sat : std_logic_vector(7 downto 0); signal numer_sat : std_logic_vector(15 downto 0); signal remain_sig2 : std_logic_vector(7 downto 0); signal quotient_hue : std_logic_vector(16 downto 0); signal denom_hue : std_logic_vector(7 downto 0); signal numer_hue : std_logic_vector(16 downto 0); signal R : STD_LOGIC_VECTOR(7 DOWNTO 0); signal V : STD_LOGIC_VECTOR(7 DOWNTO 0); signal B : STD_LOGIC_VECTOR(7 DOWNTO 0); component division PORT ( numer : IN STD_LOGIC_VECTOR (15 DOWNTO 0); denom : IN STD_LOGIC_VECTOR (7 DOWNTO 0); quotient : OUT STD_LOGIC_VECTOR (15 DOWNTO 0); remain : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) ); end component; component division_hue PORT ( numer : IN STD_LOGIC_VECTOR (16 DOWNTO 0); denom : IN STD_LOGIC_VECTOR (7 DOWNTO 0); quotient : OUT STD_LOGIC_VECTOR (16 DOWNTO 0); remain : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) ); end component; BEGIN R <= R_in; V <= V_in; B <= B_in; color_extrem : process (R, V, B) begin if R > V then -- R > V if B > R then -- B > R > V maxcolor <= B; mincolor <= V; R_max <= '0'; V_max <= '0'; elsif V > B then -- R > V > B maxcolor <= R; mincolor <= B; R_max <= '1'; V_max <= '0'; else -- R > B >= V maxcolor <= R; mincolor <= V; R_max <= '1'; V_max <= '0'; end if; else -- V >= R if not(V > B) then -- B >= V >= R maxcolor <= B; mincolor <= R; R_max <= '0'; V_max <= '0'; elsif not(B > R) then -- V >= R > B ou V > R >= B maxcolor <= V; mincolor <= B; R_max <= '0'; V_max <= '1'; else -- V >= B > R maxcolor <= V; mincolor <= R; R_max <= '0'; V_max <= '1'; end if; end if; end process; sum_dif : process (maxcolor, mincolor) begin colorsum <= ('0'&maxcolor) + ('0'&mincolor); colordif <= maxcolor - mincolor; end process; L <= colorsum; numer_sat <= colordif&"00000000"; sat : process (colordif, colorsum, quotient) begin if colordif = "00000000" then S <= "00000000"; else if colorsum(8) = '0' then denom_sat <= colorsum(7 downto 0); -- ne dépasse pas 255 S <= quotient(7 downto 0); else denom_sat <= not(colorsum(7 downto 0)); -- dépasse 255, donc 512-x => not(x) hors MSB S <= quotient(7 downto 0); end if; end if; end process; denom_hue <= colordif; hue : process (colordif, quotient_hue, R, V, B, R_max, V_max) begin if colordif = "00000000" then H <= "00000000000"; else if R_max = '1' then -- H = (G-B)/colordif + 1 (pas de négatif) numer_hue <= ('0'&V&"00000000")-('0'&B&"00000000"); H <= quotient_hue(10 downto 0) + "00100000001"; elsif V_max = '1' then -- H = 2.0 + (B-R)/colordif + 1 numer_hue <= ('0'&B&"00000000")-('0'&R&"00000000"); H <= quotient_hue(10 downto 0) + "01100000001"; else -- H = 4.0 + (R-G)/colordif + 1 numer_hue <= ('0'&R&"00000000")-('0'&V&"00000000"); H <= quotient_hue(10 downto 0) + "10100000001"; end if; end if; end process; -- Component Instantiation Statement division_sat : division PORT MAP ( numer => numer_sat, denom => denom_sat, quotient => quotient, remain => remain_sig ); division_teinte : division_hue PORT MAP ( numer => numer_hue, denom => denom_hue, quotient => quotient_hue, remain => remain_sig2 ); END a;