/* *********************************************************************
This source file is a part of the standard library of Scol
For the latest info, see http://www.scolring.org
Copyright (c) 2015 Stephane Bisaro aka Iri.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt
********************************************************************* */
/*
* 2d functions for Scol
* See http://redmine.scolring.org/projects/tutorials/wiki/Scol_usage
* for more informations
*/
/*! \file colors.pkg
* \author Scol team
* \version 0.1
* \copyright GNU Lesser General Public License 2.0 or later
* \brief Scol 2d colors API
*
*
* Important: Colors are presented as a result of mathematical calculations.
* Conversions may be inaccurate / approximate / useless.
*
* Dependancies :
* - lib/std/stdlib.pkg
*
* \example 2d/grayscale.pkg_
*
**/
/* PRIVATE FUNCTIONS */
/* Returns the complementary color from (red, green, blue)
* in : red -> I : 0 -> 255
* green -> I : 0 -> 255
* blue -> I : 0 -> 255
* out : r' -> I : 0 -> 255
* out : g' -> I : 0 -> 255
* out : b' -> I : 0 -> 255
*/
fun l2d_colorsComplementaryFromRGB (r, g, b)=
[255-r 255-g 255-b];;
/* Returns the complementary color from (hue, saturation, value)
* in : hue -> F : 0.0 -> 360.0
* saturation -> F : 0.0 -> 1.0
* value -> F : 0.0 -> 1.0
* out : h' -> F : 0.0 -> 360.0
* out : s' -> F : 0.0 -> 1.0
* out : v' -> F : 0.0 -> 1.0
*/
fun l2d_colorsComplementaryFromHSV (H, S, V)=
let [nil nil nil] -> [h s v] in
(
if H >=. 180.0 then
set h = H-.180.0
else
set h = H+.180.0;
set v = (V*.(S-.1.0))+.1.0;
if v == 0.0 then
set s = 0.0
else
set s = (V*.S)/.v;
// v et s apporte une correction qui n'est pas jugé utile par tous. Actu, je ne l'utilise pas.
[h S V]
);;
/*
let if H >=. 180.0 then H-.180.0 else H+.180.0 -> h in
[h (V*.S)/.((V*.(S-.1.0))+.1.0) V*.(S-.1.0)+.1.0];;*/
//[h S V];;
/* Returns the natural color system (ncs) code, if it exists, from a RGB 24-bits color
* in : red -> I : 0 -> 255
* green -> I : 0 -> 255
* blue -> I : 0 -> 255
* out : ncs -> S : the color string or "ERROR"
*
* note : Don't use this, it works incorrectly
*/
fun l2d_colors_rgb2ncs (red, green, blue)= // ncs : natural color system
let [nil nil nil] -> [r g b] in
let [nil nil nil] -> [m iw y] in
let [nil nil nil nil nil] -> [c1 c2 n c s] in
(
set r = (itof red)/.255.0;
set g = (itof green)/.255.0;
set b = (itof blue)/.255.0;
set m = minf minf r g b;
set iw = ftoi (m*.100.0);
set y = 0.0;
set r = r-.m;
set g = g-.m;
set b = b-.m;
if (r == 0.0) && (g == 0.0) && (b == 0.0) then
if iw == 0 then
(
set c1 = "B";
set c2 = " ";
set n = "0";
set c = "0";
)
else if iw == 100 then
(
set c1 = "W";
set c2 = " ";
set n = "0";
set c = "0";
)
else
(
set c1 = "N";
set c2 = " ";
set n = "0";
set c = "0";
)
else if (r == 0.0) && (b == 0.0) then
(
set c1 = "G";
set c2 = " ";
set n = "0";
set c = itoa ftoi (g*.100.0);
)
else if (r == 0.0) && (g == 0.0) then
(
set c1 = "B";
set c2 = " ";
set n = "0";
set c = itoa ftoi (b*.100.0);
)
else if (g == 0.0) && (b == 0.0) then
(
set c1 = "R";
set c2 = " ";
set n = "0";
set c = itoa ftoi (r*.100.0);
)
else if r == g then
(
set y = g;
set r = 0.0;
set g = 0.0;
set c1 = "Y";
set c2 = " ";
set n = "0";
set c = itoa ftoi (y*.100.0);
)
else if r == 0.0 then
(
set c1 = "G";
set c2 = "B";
set n = itoa ftoi ((b*.100.0)/.(g+.b));
set y = 0.0;
nil
)
else if g == 0.0 then
(
set c1 = "B";
set c2 = "R";
set n = itoa ftoi ((r*.100.0)/.(r+.b));
set y = 0.0;
nil
)
else if (b == 0.0) && (g <. r) then
(
set c1 = "R";
set c2 = "Y";
set y = g;
set r = r-.g;
set g = 0.0;
set n = itoa ftoi ((y*.100.0)/.(r+.y));
)
else if (b == 0.0) && (r <. g) then
(
set c1 = "Y";
set c2 = "G";
set y = r;
set g = g-.r;
set r = 0.0;
set n = itoa ftoi ((g*.100.0)/.(g+.y));
)
else
(
set c1 = "ERROR";
set c2 = "";
set n = "";
set c = "";
set s = "";
);
if c == nil then
set c = itoa ftoi ((maxf maxf maxf r g b y)*.100.0);
if s == nil then
set s = itoa ftoi (100.0-.(atof c)-.(itof iw));
if (atoi c) < 10 then
set c = strcat "0" c;
if (atoi s) < 10 then
set s = strcat "0" s;
sprintf "%s.%s-%s.%s.%s" [s c c2 n c1];
);;
/* Converts a RGB component from integer to hexadecimal
* in : red -> I : 0 -> 255
* green -> I : 0 -> 255
* blue -> I : 0 -> 255
* out : red -> S : in hex
* out : green -> S : in hex
* out : blue -> S : in hex
*/
fun l2d_colors_rgb2hex (red, green, blue)=
[itoh red itoh green itoh blue];;
/* Converts a RGB component from hexadecimal to integer
* in : red -> S : 00 -> FF
* green -> S : 00 -> FF
* blue -> S : 00 -> FF
* out : red -> I : 0 -> 255
* green -> I : 0 -> 255
* blue -> I : 0 -> 255
*/
fun l2d_colors_hex2int (red, green, blue)=
[htoi red htoi green htoi blue];;
/* Converts a RGB 24-bits color to its CMYK components
* in : red -> I : 0 -> 255
* green -> I : 0 -> 255
* blue -> I : 0 -> 255
* out : cyan -> I : 0 -> 100
* out : magenta -> I : 0 -> 100
* out : yellow -> I : 0 -> 100
* out : key (black) -> I : 0 -> 100
*/
fun l2d_colors_rgb2cmyk (red, green, blue)=
let [nil nil nil] -> [r g b] in
let nil -> K in
let [nil nil nil] -> [Cw Mw Yw] in // C M Y from white space
let [nil nil nil] -> [Cb Mb Yb] in // C M Y from black space
(
set r = (itof red)/.255.0;
set g = (itof green)/.255.0;
set b = (itof blue)/.255.0;
// calculates the same first CMY values for the two spaces
set Cb = 1.0-.r;
set Mb = 1.0-.g;
set Yb = 1.0-.b;
set K = minf minf Cb Mb Yb; // key (black)
// from white space (used by GIMP or Photoshop by example)
if K == 1.0 then
(
set Cw = 0.0;
set Mw = 0.0;
set Yw = 0.0;
)
else
(
set Cw = (Cb-.K)/.(1.0-.K);
set Mw = (Mb-.K)/.(1.0-.K);
set Yw = (Yb-.K)/.(1.0-.K);
);
// from black space (used by LibreOffice or MS Office by example)
if K == 1.0 then
(
set Cb = 0.0;
set Mb = 0.0;
set Yb = 0.0;
)
else
(
set Cb = Cb-.K;
set Mb = Mb-.K;
set Yb = Yb-.K;
);
set K = K*.100.0;
[[(ftoi Cb)*100 (ftoi Mb)*100 (ftoi Yb)*100 ftoi K] [(ftoi Cw)*100 (ftoi Mw)*100 (ftoi Yw)*100 ftoi K]]
);;
/* Converts a RGB 24-bits color to its CMYK components
* in : cyan -> I : 0 -> 100
* : magenta -> I : 0 -> 100
* : yellow -> I : 0 -> 100
* : key (black) -> I : 0 -> 100
* : space -> I : 1 to 'white' space
* out : red -> I : 0 -> 255
* out : green -> I : 0 -> 255
* out : blue -> I : 0 -> 255
*/
fun l2d_colors_cmyk2rvb (cyan, magenta, yellow, key, space)=
let [nil nil nil] -> [r g b] in
let [nil nil nil nil] -> [c m y k] in
(
set c = (itof cyan)/.100.0;
set m = (itof magenta)/.100.0;
set y = (itof yellow)/.100.0;
set k = (itof key)/.100.0;
// CMJK to CMJ space
if space then // 1 : white space
(
set c = (c*.(1.0-.k))+.k;
set m = (m*.(1.0-.k))+.k;
set y = (y*.(1.0-.k))+.k;
)
else // 'black' space
(
set c = c+.k;
set m = m+.k;
set y = y+.k;
);
set r = 1.0-.c;
set g = 1.0-.m;
set b = 1.0-.y;
[(ftoi r)*255 (ftoi g)*255 (ftoi b)*255]
);;
/* Return the three RGB components from a 24-bits RGB color */
fun l2d_colorsrgb2c (c) = /* c = 24 bits color */
let (c>>16) & 255 -> b in
let (c>>8) & 255 -> g in
let c & 255 -> r in
[r g b];;
/* Convert (hue, saturation, value) to (red, green, blue)
* in : hue -> I : 0 -> 360
* saturation -> I : 0 -> 100
* value -> I : 0 -> 100
* out : r -> F : 0.0 -> 1.0
* out : g -> F : 0.0 -> 1.0
* out : b -> F : 0.0 -> 1.0
*/
fun l2d_colors_hsv2rgb (hue, saturation, value) =
let [nil nil nil] -> [h s v] in
//let [nil nil nil nil] -> [C H X m] in
let [nil nil nil nil nil] -> [C H l m n] in
(
set h = itof hue;
//set h = (itof hue)/.360.0;
set s = (itof saturation)/.100.0;
set v = (itof value)/.100.0;
if s == 0.0 then
[v v v]
else
(
set H = itof mod (ftoi h)/60 6;
set C = (h/.60.0)-.H;
set l = v*.(1.0-.s);
set m = v*.(1.0-.(C*.s));
set n = v*.(1.0-.((1.0-.C)*.s));
if H == 0.0 then
[v n l]
else if H == 1.0 then
[m v l]
else if H == 2.0 then
[l v n]
else if H == 3.0 then
[l m v]
else if H == 4.0 then
[n l v]
else
[v l m]
)
);;
/* Convert (red, green, blue) to (hue, saturation, value)
* in : r -> I : 0 -> 255
* in : g -> I : 0 -> 255
* in : b -> I : 0 -> 255
* out : h -> F : 0.0 -> 360.0
* out : s -> F : 0.0 -> 1.0
* out : v -> F : 0.0 -> 1.0
*/
fun l2d_colors_rgb2hsv (red, green, blue)=
let [nil nil nil] -> [r g b] in
let [nil nil nil] -> [M m C] in
let [nil nil nil] -> [h s v] in
(
set r = (itof red)/.255.0;
set g = (itof green)/.255.0;
set b = (itof blue)/.255.0;
set M = maxf maxf r g b;
set m = minf minf r g b;
set C = M-.m;
if M == m then
set h = 0.0
else if M == r then
let (60.0*.((g-.b)/.C))+.360.0 -> f in
let modf f/.360.0 0.0 -> q in // decimal part of the division
set h = q+.itof mod ftoi f 360
else if M == g then
set h = (60.0*.((b-.r)/.C))+.120.0
else if M == b then
set h = (60.0*.((r-.g)/.C))+.240.0;
set v = M;
if M == 0.0 then
set s = 0.0
else
set s = 1.0-.(m/.M);
[h s v]
);;
// used by l2d_colors_hsl2rgb below
fun l2d_colors_hue2rgb (m1, m2, h)=
if h <. 0.0 then
set h = h+.1.0;
if h >. 1.0 then
set h = h-.1.0;
if (h*.6.0) <. 1.0 then
m1+.((m2-.m1)*.h*.6.0)
else if (h*.2.0) <. 1.0 then
m2
else if (h*.3.0) <. 2.0 then
m1+.((m2-.m1)*.((2.0/.3.0)-.h)*.6.0)
else
m1;;
/* Converts a HSL color to a RGB color
* in : hue -> I : 0..360
* : saturation -> I : 0..100
* : lightness -> I : 0..100
* out: red -> F : 0.0..1.0
* : green -> F : 0.0..1.0
* : blue -> F : 0.0..1.0
*/
fun l2d_colors_hsl2rgb (hue, saturation, lightness)=
let [nil nil nil] -> [h s l] in
let [nil nil nil nil nil] -> [m1 m2 r g b] in
(
set h = itof hue;
set s = (itof saturation)/.100.0;
set l = (itof lightness)/.100.0;
if l <=. 0.5 then
set m2 = l*.(s+.1.0)
else
set m2 = l+.s-.(l*.s);
set m1 = (l*.2.0)-.m2;
set r = l2d_colors_hue2rgb m1 m2 h+.(1.0/.3.0);
set g = l2d_colors_hue2rgb m1 m2 h;
set b = l2d_colors_hue2rgb m1 m2 h-.(1.0/.3.0);
[r g b]
);;
/* Converts a RGB color to a HSL color
* in : red -> I : 0..255
* : green -> I : 0..255
* : blue -> I : 0..255
* out: hue -> F : 0.0..1.0
* : saturation -> F : 0.0..1.0
* : lightness -> F : 0.0..1.0
*/
fun l2d_colors_rgb2hsl (red, green, blue)=
let [nil nil nil] -> [r g b] in
let [nil nil nil] -> [m M C] in
let [nil nil nil] -> [h s l] in
(
set r = (itof red)/.255.0;
set g = (itof green)/.255.0;
set b = (itof blue)/.255.0;
set m = minf minf r g b;
set M = maxf maxf r g b;
set C = M-.m;
set l = (M+.m)/.2.0;
if C == 0.0 then
(
set h = 0.0; // convention, else undefined
set s = 0.0
)
else
(
if l <. 0.5 then
set s = C/.(m+.M)
else
set s = C/.(2.0-.M-.m);
let (((M-.r)/.6.0)+.(C/.2.0))/.C -> cr in
let (((M-.g)/.6.0)+.(C/.2.0))/.C -> cg in
let (((M-.b)/.6.0)+.(C/.2.0))/.C -> cb in
if M == r then
set h = cb-.cg
else if M == g then
set h = (1.0/.3.0)+.cr-.cb
else // M == b
set h = (2.0/.30.)+.cg-.cr;
if h <. 0.0 then
//++h // not an integer
set h = h+.1.0
else if h >. 1.0 then
//--h; // not an integer
set h = h-.1.0;
);
[h s l]
);;
/* Returns the 24-bits colors from its three RGB components
* in : red -> I
* in : green -> I
* in : blue -> I
* out : color -> I
*/
fun l2d_colorsrgb (r, g, b)=
make_rgb r g b;;
/* Returns the color from a standardized css name
* in : name -> S : a color name
* out : tuple [S S [I I I]]
* : - name -> S : the same given name
* : - hex -> S : the hexadecimal value
* : - rgb -> [I I I] : the three rgb components in integer
* or nil if the color name is not found
*/
fun l2d_colorscss (name)=
let strextr _getpack _checkpack "lib/2d/rscs/colors_css" -> l in
let switchstri l name -> r in
if r == nil then
nil
else
[name hd r [atoi hd tl r atoi hd tl tl r atoi hd tl tl tl r]];;
/* Returns the gray value from a RGB color ("average method")
*
* Used formula is : Gray = (Red + Green + Blue) / 3
*
* in : red -> I : 0..255
* : green -> I : 0..255
* : blue -> I : 0..255
* out : gray -> I : 0..255
* : gray -> I : 0..255
* : gray -> I : 0..255
*/
fun l2d_colorsgrayscaleOne (r, g, b)=
let (r+g+b)/3 -> a in
[a a a];;
/* Returns the gray value from a RGB color ("human eye correction")
*
* Used formula is : Gray = Red * 0.3 + Green * 0.59 + Blue * 0.11
*
* in : red -> I : 0..255
* : green -> I : 0..255
* : blue -> I : 0..255
* out : gray -> I : 0..255
* : gray -> I : 0..255
* : gray -> I : 0..255
*/
fun l2d_colorsgrayscaleTwoA (r, g, b)=
let ftoi (((itof r)*.0.3)+.((itof g)*.0.59)+.((itof b)*.0.11)) -> a in
[a a a];;
/* Returns the gray value from a RGB color ("human eye correction")
*
* Used formula is : Gray = Red * 0.2126 + Green * 0.7152 + Blue * 0.0722
*
* in : red -> I : 0..255
* : green -> I : 0..255
* : blue -> I : 0..255
* out : gray -> I : 0..255
* : gray -> I : 0..255
* : gray -> I : 0..255
*/
fun l2d_colorsgrayscaleTwoB (r, g, b)=
let ftoi (((itof r)*.0.2126)+.((itof g)*.0.7152)+.((itof b)*.0.0722)) -> a in
[a a a];;
/* Returns the gray value from a RGB color ("human eye correction")
*
* Used formula is : Gray = Red * 0.299 + Green * 0.587 + Blue * 0.114
*
* in : red -> I : 0..255
* : green -> I : 0..255
* : blue -> I : 0..255
* out : gray -> I : 0..255
* : gray -> I : 0..255
* : gray -> I : 0..255
*/
fun l2d_colorsgrayscaleTwoC (r, g, b)=
let ftoi (((itof r)*.0.299)+.((itof g)*.0.587)+.((itof b)*.0.114)) -> a in
[a a a];;
/* Returns the gray value from a RGB color ("desaturation")
*
* Used formula is : Gray = (Max(Red, Green, Blue) + Min(Red, Green, Blue)) / 2
*
* in : red -> I : 0..255
* : green -> I : 0..255
* : blue -> I : 0..255
* out : gray -> I : 0..255
* : gray -> I : 0..255
* : gray -> I : 0..255
*/
fun l2d_colorsgrayscaleThree (r, g, b)=
let [nil nil nil] -> [m M a] in
(
set m = min min r g b;
set M = max max r g b;
set a = (M+m)/2;
[a a a]
);;
/* Returns the gray value from a RGB color ("decomposition")
*
* Used formula is : Gray = Max (Red, Green, Blue) or Gray = Min (Red, Green, Blue)
*
* in : red -> I : 0..255
* : green -> I : 0..255
* : blue -> I : 0..255
* : flag -> I : 1 : with Maximun, 0 with Minimum
* out : gray -> I : 0..255
* : gray -> I : 0..255
* : gray -> I : 0..255
*/
fun l2d_colorsgrayscaleFour (r, g, b, f)=
set f = std_clamp f 0 1;
let if f then max max r g b
else min min r g b
-> a in
[a a a];;
/* Returns the gray value from a RGB color ("single gray channel")
*
* Used formula is : Gray = Red or Gray = Green or Gray = Blue
*
* in : red -> I : 0..255
* : green -> I : 0..255
* : blue -> I : 0..255
* : flag -> I : 0 to red, 1 to green, 2 to blue
* out : gray -> I : 0..255
* : gray -> I : 0..255
* : gray -> I : 0..255
*/
fun l2d_colorsgrayscaleFive (r, g, b, f)=
set f = std_clamp f 0 2;
let if f == 2 then b
else if f then g
else r
-> a in
[a a a];;
/* Returns the gray value from a RGB color ("custom gray shaders")
*
* The formula depends on the given shaders number.
*
* in : red -> I : 0..255
* : green -> I : 0..255
* : blue -> I : 0..255
* : shaders -> I : 2..256 : 2 -> black and white, 256 -> like "average method"
* out : gray -> I : 0..255
* : gray -> I : 0..255
* : gray -> I : 0..255
*/
fun l2d_colorsgrayscaleSix (r, g, b, s)=
set s = std_clamp s 2 256;
let [nil nil nil] -> [c v a] in
(
//set c = 255.0/.((itof s)-.1.0);
set c = 255/(s-1);
set v = (r+g+b)/3;
//set a = ftoi ((((itof v)/.c)+.0.5)*.c);
set a = (ftoi ((((itof v)/.(itof c))+.0.5)))*c;
[a a a]
);;
/* PUBLIC FUNCTIONS */
/*! Convert the three RGB components to the three HSV components
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [F F F]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \return [F F F] : the hue [0.0 .. 360.0], the saturation [0.0 .. 1.0], the value [0.0 .. 1.0] components
*/
fun l2d_colorsConvertRGB2HSV (iRed, iGreen, iValue)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iValue = std_clamp iValue 0 255;
l2d_colors_rgb2hsv iRed iGreen iValue;;
/*! Convert the three HSV components to the three RGB components
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [F F F]
*
* \param I : the hue component [0..360]
* \param I : the saturation component [0..100]
* \param I : the value component [0..100]
* \return [F F F] : the red [0.0 .. 1.0], the green [0.0 .. 1.0], the blue [0.0 .. 1.0] components
*/
fun l2d_colorsConvertHSV2RGB (iHue, iSaturation, iValue)=
set iHue = std_clamp iHue 0 360;
set iSaturation = std_clamp iSaturation 0 100;
set iValue = std_clamp iValue 0 100;
l2d_colors_hsv2rgb iHue iSaturation iValue;;
/*! Convert a 24 bits color to its three RGB components
*
* \ingroup l2d_colors
* Prototype : fun [I] [I I I]
*
* \param I : a 24-bits color (0..16777216)
* \return [I I I] : the red [0..255], the green [0..255], the blue [0..255] components
*/
fun l2d_colors2RGB (iColor)=
set iColor = std_clamp iColor 0 16777216;
l2d_colorsrgb2c iColor;;
/*! Convert the three RGB components to a 24-bits color
*
* \ingroup l2d_colors
* Prototype : fun [I I I] I
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \return I : the 24-bits color
*/
fun l2d_colorsRGB2C (iRed, iGreen, iBlue)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
l2d_colorsrgb iRed iGreen iBlue;;
/*! Gets the complementary color from a RGB color
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [I I I]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \return [I I I] : the three RGB components of the complementary (0..255 for each)
*/
fun l2d_colorsGetComplFromRGB (iRed, iGreen, iBlue)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
l2d_colorsComplementaryFromRGB iRed iGreen iBlue;;
/*! Gets the complementary color from a HSV color
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [I I I]
*
* \param I : the hue component [0..360]
* \param I : the saturation component [0..100]
* \param I : the value component [0..100]
* \return [I I I] : the three HSV components of the complementary (0..360 for hue, 0..100 for saturation and value)
*/
fun l2d_colorsGetComplFromHSV (iHue, iSaturation, iValue)=
set iHue = std_clamp iHue 0 360;
set iSaturation = std_clamp iSaturation 0 100;
set iValue = std_clamp iValue 0 100;
let l2d_colorsComplementaryFromHSV itof iHue (itof iSaturation)/.100.0 (itof iValue)/.100.0 -> [h s v] in
[ftoi h (ftoi s*.100.0) (ftoi v*.100.0)];;
/*! Converts a RGB 24-bits color to its CMYK components
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [[I I I I] [I I I I]]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \return [[I I I I] [I I I I]] : the four CMYK components (0..100 for each)
* - the first tuple returns the components from the 'black' (or 'full') space. It is used by LibreOffice or MS Office by example.
* - the second tuple returns the components from the 'white' space. It is used by GIMP or Adobe Photoshop by example.
*/
fun l2d_colorsConvertRGB2CMYK(iRed, iGreen, iBlue)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
l2d_colors_rgb2cmyk iRed iGreen iBlue;;
/*! Converts a CMYK color to its RGB components (8-bits per component)
*
* \ingroup l2d_colors
* Prototype : fun [I I I I I] [I I I]
*
* \param I : the cyan component [0..100]
* \param I : the magenta component [0..100]
* \param I : the yellow component [0..100]
* \param I : the key (black) component [0..100]
* \param I : the space identifier : 1 for CMYK from the 'white' space, other integer from the 'black' space
* \return [I I I] : the three RVB components (0..255 for each).
*/
fun l2d_colorsConvertCMYK2RGB (iCyan, iMagenta, iYellow, iKey, iSpace)=
set iCyan = std_clamp iCyan 0 100;
set iMagenta = std_clamp iMagenta 0 100;
set iYellow = std_clamp iYellow 0 100;
set iKey = std_clamp iKey 0 100;
l2d_colors_cmyk2rvb iCyan iMagenta iYellow iKey iSpace;;
/*! Converts a RGB 24-bits color from integer to hexadecimal values
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [S S S]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \return [S S S] : the three hexadecimal components (00..FF for each)
*/
fun l2d_colorsConvertINT2HEX (iRed, iGreen, iBlue)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
l2d_colors_rgb2hex iRed iGreen iBlue;;
/*! Converts a RGB 24-bits color from hexadecimal to integer values
*
* \ingroup l2d_colors
* Prototype : fun [S S S] [I I I]
*
* \param S : the red component in hex
* \param S : the green component in hex
* \param S : the blue component in hex
* \return [I I I] : the three hexadecimal components (0..255 for each)
*/
fun l2d_colorsConvertHEX2INT (szRed, szGreen, szBlue)=
l2d_colors_hex2int szRed szGreen szBlue;;
/*! Gets a basic color from its standardized CSS name.
*
* black sylver gray white maroon red purple fuchsia green lime olive yellow navy blue teal aqua
* \see http://www.w3.org/TR/css3-color/#html4
*
* \ingroup l2d_colors
* Prototype : fun [S] [S S [I I I]]
*
* \param S : a css color name
* \return [S S [I I I]] : a tuple or nil if the color name is not found in the resources
* - S : the same given name in argument
* - S : the hexadecimal value
* - [I I I] : the three hexadecimal rgb components (0..255 for each)
*/
fun l2d_colorsFromCssByName (szName)=
l2d_colorscss szName;;
/*! Converts a HSL color to a RGB color
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [I I I]
*
* \param I : the hue component [0..360]
* \param I : the saturation component [0..100]
* \param I : the lightness component [0..100]
* \return [I I I] : the three components : red, green, blue (0..255 for each)
*/
fun l2d_colorsConvertHSL2RGB (iHue, iSaturation, iLightness)=
set iHue = std_clamp iHue 0 360;
set iSaturation = std_clamp iSaturation 0 100;
set iLightness = std_clamp iLightness 0 100;
let l2d_colors_hsl2rgb iHue iSaturation iLightness -> [r g b] in
[ftoi (r*.255.0) ftoi (g*.255.0) ftoi (b*.255.0)];;
/*! Converts a RGB 24-bits color to a HSL color
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [I I I]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \return [I I I] : the three components : hue, saturation, lightness (0..100 for each, except hue 0..360)
*/
fun l2d_colorsConvertRGB2HSL (iRed, iGreen, iBlue)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
let l2d_colors_rgb2hsl iRed iGreen iBlue -> [h s l] in
[ftoi (h*.360.0) ftoi (s*.100.0) ftoi (l*.100.0)];;
/*! Returns the gray value from a RGB color : "average method"
*
* The formula is : \f$Gray = (Red + Green + Blue) / 3\f$
*
* This is the faster and the simpler method. It gives a reasonably grayscale
* equivalent but it is the lesser for the human eye.
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [I I I]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \return [I I I] : the three gray RGB components (0..255 for each)
*/
fun l2d_colorsGrayAverage (iRed, iGreen, iBlue)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
l2d_colorsgrayscaleOne iRed iGreen iBlue;;
/*! Returns the gray value from a RGB color : "human eye correction A"
*
* The formula is : \f$Gray = Red * 0.3 + Green * 0.59 + Blue * 0.11\f$
*
* The human eye perceive green more strongly than red, and red more strongly
* than blue. The cause is evolutionary biology perspective, much of the
* natural world appears in shades of green. The resulting contrast is near
* of a photograph from an argentic camera.
*
* For example, GIMP and Adobe Photoshop use this formula in theirs threatments.
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [I I I]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \return [I I I] : the three gray RGB components (0..255 for each)
*
* \see l2d_colorsGrayHumanB
* \see l2d_colorsGrayHumanC
*/
fun l2d_colorsGrayHumanA (iRed, iGreen, iBlue)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
l2d_colorsgrayscaleTwoA iRed iGreen iBlue;;
/*! Returns the gray value from a RGB color : "human eye correction B"
*
* The formula is : \f$Gray = Red * 0.2126 + Green * 0.7152 + Blue * 0.0722\f$
*
* The human eye perceive green more strongly than red, and red more strongly
* than blue. The cause is evolutionary biology perspective, much of the
* natural world appears in shades of green.
*
* There is disagreement on the best formula for this type of grayscale conversion.
* Here is the definition by the ITU (BT.709) : http://www.itu.int/rec/R-REC-BT.709/en
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [I I I]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \return [I I I] : the three gray RGB components (0..255 for each)
*
* \see l2d_colorsGrayHumanA
* \see l2d_colorsGrayHumanC
*/
fun l2d_colorsGrayHumanB (iRed, iGreen, iBlue)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
l2d_colorsgrayscaleTwoB iRed iGreen iBlue;;
/*! Returns the gray value from a RGB color : "human eye correction C"
*
* The formula is : \f$Gray = Red * 0.299 + Green * 0.587 + Blue * 0.114\f$
*
* The human eye perceive green more strongly than red, and red more strongly
* than blue. The cause is evolutionary biology perspective, much of the
* natural world appears in shades of green.
*
* There is disagreement on the best formula for this type of grayscale conversion.
* Here is the definition by the ITU (BT.601) : http://www.itu.int/rec/R-REC-BT.709/en
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [I I I]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \return [I I I] : the three gray RGB components (0..255 for each)
*
* \see l2d_colorsGrayHumanA
* \see l2d_colorsGrayHumanB
*/
fun l2d_colorsGrayHumanC (iRed, iGreen, iBlue)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
l2d_colorsgrayscaleTwoC iRed iGreen iBlue;;
/*! Returns the gray value from a RGB color : "Desaturation"
*
* The formula is : \f$Gray = (Max(Red, Green, Blue) + Min(Red, Green, Blue)) / 2\f$
*
* Desaturating an image works by converting the RGB in HSL format and
* forcing the saturation value to zero. This formula is a shortcut for
* a more complex conversion.
*
* The desaturation results in a flatter grayscale image, like with a cheap camera.
*
* \ingroup l2d_colors
* Prototype : fun [I I I] [I I I]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \return [I I I] : the three gray RGB components (0..255 for each)
*/
fun l2d_colorsGrayDesaturation (iRed, iGreen, iBlue)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
l2d_colorsgrayscaleThree iRed iGreen iBlue;;
/*! Returns the gray value from a RGB color : "Decomposition"
*
* The formula is : \f$Gray = Max (Red, Green, Blue)\f$ or \f$Gray = Min (Red, Green, Blue)\f$
*
* To decompose an image, the function forces each pixel to the highest
* (maximum) or lowest (minimum) of its red, green, and blue values. This
* doesn't care which channel the value comes from.
*
* The "maximum" provides a brighter grayscale image, while the "minimum"
* provides a darker one.
*
* \ingroup l2d_colors
* Prototype : fun [I I I I] [I I I]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \param I : a flag : 1 with Maximun, 0 with Minimum
* \return [I I I] : the three gray RGB components (0..255 for each)
*/
fun l2d_colorsGrayDecomposition (iRed, iGreen, iBlue, iFlag)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
l2d_colorsgrayscaleFour iRed iGreen iBlue iFlag;;
/*! Returns the gray value from a RGB color : "Single gray channel"
*
* The formula is : \f$Gray = Red\f$ or \f$Gray = Green\f$ or \f$Gray = Blue\f$
*
* Usually, this is the worst method. The gray comes from a single color channel.
*
* \ingroup l2d_colors
* Prototype : fun [I I I I] [I I I]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \param I : a flag : 0 to red, 1 to green, 2 to blue channel
* \return [I I I] : the three gray RGB components (0..255 for each)
*/
fun l2d_colorsGraySingleChannel (iRed, iGreen, iBlue, iFlag)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
l2d_colorsgrayscaleFive iRed iGreen iBlue iFlag;;
/*! Returns the gray value from a RGB color : "Custom shaders"
*
* This method works by selecting X gray values, equally spread between
* zero luminance (black) and full luminance (white).
*
* \ingroup l2d_colors
* Prototype : fun [I I I I] [I I I]
*
* \param I : the red component [0..255]
* \param I : the green component [0..255]
* \param I : the blue component [0..255]
* \param I : the shaders number : [2..256] : 2 -> black and white until 256 -> like "average method"
* \return [I I I] : the three gray RGB components (0..255 for each)
*/
fun l2d_colorsGrayCustom (iRed, iGreen, iBlue, iFlag)=
set iRed = std_clamp iRed 0 255;
set iGreen = std_clamp iGreen 0 255;
set iBlue = std_clamp iBlue 0 255;
l2d_colorsgrayscaleSix iRed iGreen iBlue iFlag;;