Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  sksl_shared.sksl   Sprache: unbekannt

 
// Intrinsics that are available to public SkSL (SkRuntimeEffect)

// See "The OpenGL ES Shading Language, Section 8"

// 8.1 : Angle and Trigonometry Functions
$pure $genType  radians($genType  degrees);
$pure $genHType radians($genHType degrees);
$pure $genType  degrees($genType  radians);
$pure $genHType degrees($genHType radians);

$pure $genType  sin($genType  angle);
$pure $genHType sin($genHType angle);
$pure $genType  cos($genType  angle);
$pure $genHType cos($genHType angle);
$pure $genType  tan($genType  angle);
$pure $genHType tan($genHType angle);

$pure $genType  asin($genType  x);
$pure $genHType asin($genHType x);
$pure $genType  acos($genType  x);
$pure $genHType acos($genHType x);
$pure $genType  atan($genType  y, $genType  x);
$pure $genHType atan($genHType y, $genHType x);
$pure $genType  atan($genType  y_over_x);
$pure $genHType atan($genHType y_over_x);

// 8.1 : Angle and Trigonometry Functions (GLSL ES 3.0)
$pure $es3 $genType  sinh($genType x);
$pure $es3 $genHType sinh($genHType x);
$pure $es3 $genType  cosh($genType x);
$pure $es3 $genHType cosh($genHType x);
$pure $es3 $genType  tanh($genType x);
$pure $es3 $genHType tanh($genHType x);
$pure $es3 $genType  asinh($genType x);
$pure $es3 $genHType asinh($genHType x);
$pure $es3 $genType  acosh($genType x);
$pure $es3 $genHType acosh($genHType x);
$pure $es3 $genType  atanh($genType x);
$pure $es3 $genHType atanh($genHType x);

// 8.2 : Exponential Functions
$pure $genType  pow($genType  x, $genType  y);
$pure $genHType pow($genHType x, $genHType y);
$pure $genType  exp($genType  x);
$pure $genHType exp($genHType x);
$pure $genType  log($genType  x);
$pure $genHType log($genHType x);
$pure $genType  exp2($genType  x);
$pure $genHType exp2($genHType x);
$pure $genType  log2($genType  x);
$pure $genHType log2($genHType x);

$pure $genType  sqrt($genType  x);
$pure $genHType sqrt($genHType x);
$pure $genType  inversesqrt($genType  x);
$pure $genHType inversesqrt($genHType x);

// 8.3 : Common Functions
$pure $genType  abs($genType  x);
$pure $genHType abs($genHType x);
$pure $genType  sign($genType  x);
$pure $genHType sign($genHType x);
$pure $genType  floor($genType  x);
$pure $genHType floor($genHType x);
$pure $genType  ceil($genType  x);
$pure $genHType ceil($genHType x);
$pure $genType  fract($genType  x);
$pure $genHType fract($genHType x);
$pure $genType  mod($genType  x, float     y);
$pure $genType  mod($genType  x, $genType  y);
$pure $genHType mod($genHType x, half      y);
$pure $genHType mod($genHType x, $genHType y);

$pure $genType  min($genType  x, $genType  y);
$pure $genType  min($genType  x, float     y);
$pure $genHType min($genHType x, $genHType y);
$pure $genHType min($genHType x, half      y);
$pure $genType  max($genType  x, $genType  y);
$pure $genType  max($genType  x, float     y);
$pure $genHType max($genHType x, $genHType y);
$pure $genHType max($genHType x, half      y);
$pure $genType  clamp($genType  x, $genType  minVal, $genType  maxVal);
$pure $genType  clamp($genType  x, float     minVal, float     maxVal);
$pure $genHType clamp($genHType x, $genHType minVal, $genHType maxVal);
$pure $genHType clamp($genHType x, half      minVal, half      maxVal);
$pure $genType  saturate($genType  x);  // SkSL extension
$pure $genHType saturate($genHType x);  // SkSL extension
$pure $genType  mix($genType  x, $genType  y, $genType a);
$pure $genType  mix($genType  x, $genType  y, float a);
$pure $genHType mix($genHType x, $genHType y, $genHType a);
$pure $genHType mix($genHType x, $genHType y, half a);
$pure $genType  step($genType  edge, $genType x);
$pure $genType  step(float     edge, $genType x);
$pure $genHType step($genHType edge, $genHType x);
$pure $genHType step(half      edge, $genHType x);
$pure $genType  smoothstep($genType  edge0, $genType  edge1, $genType  x);
$pure $genType  smoothstep(float     edge0, float     edge1, $genType  x);
$pure $genHType smoothstep($genHType edge0, $genHType edge1, $genHType x);
$pure $genHType smoothstep(half      edge0, half      edge1, $genHType x);

// 8.3 : Common Functions (GLSL ES 3.0)
$pure $es3 $genIType abs($genIType x);
$pure $es3 $genIType sign($genIType x);
$pure $es3 $genIType floatBitsToInt ($genType  value);
$pure $es3 $genUType floatBitsToUint($genType  value);
$pure $es3 $genType  intBitsToFloat ($genIType value);
$pure $es3 $genType  uintBitsToFloat($genUType value);
$pure $es3 $genType  trunc($genType  x);
$pure $es3 $genHType trunc($genHType x);
$pure $es3 $genType  round($genType  x);
$pure $es3 $genHType round($genHType x);
$pure $es3 $genType  roundEven($genType  x);
$pure $es3 $genHType roundEven($genHType x);
$pure $es3 $genIType min($genIType x, $genIType y);
$pure $es3 $genIType min($genIType x, int y);
$pure $es3 $genUType min($genUType x, $genUType y);
$pure $es3 $genUType min($genUType x, uint y);
$pure $es3 $genIType max($genIType x, $genIType y);
$pure $es3 $genIType max($genIType x, int y);
$pure $es3 $genUType max($genUType x, $genUType y);
$pure $es3 $genUType max($genUType x, uint y);
$pure $es3 $genIType clamp($genIType x, $genIType minVal, $genIType maxVal);
$pure $es3 $genIType clamp($genIType x, int minVal, int maxVal);
$pure $es3 $genUType clamp($genUType x, $genUType minVal, $genUType maxVal);
$pure $es3 $genUType clamp($genUType x, uint minVal, uint maxVal);
$pure $es3 $genType  mix($genType  x, $genType  y, $genBType a);
$pure $es3 $genHType mix($genHType x, $genHType y, $genBType a);

// 8.3 : Common Functions (GLSL ES 3.0) -- cannot be used in constant-expressions
$pure $es3 $genBType isnan($genType  x);
$pure $es3 $genBType isnan($genHType x);
$pure $es3 $genBType isinf($genType  x);
$pure $es3 $genBType isinf($genHType x);
      $es3 $genType  modf($genType  x, out $genType  i);
      $es3 $genHType modf($genHType x, out $genHType i);

// 8.4 : Floating-Point Pack and Unpack Functions (GLSL ES 3.0)
$pure $es3 uint packUnorm2x16(float2 v);
$pure $es3 float2 unpackUnorm2x16(uint p);

// 8.5 : Geometric Functions
$pure float length($genType  x);
$pure half  length($genHType x);
$pure float distance($genType  p0, $genType  p1);
$pure half  distance($genHType p0, $genHType p1);
$pure float dot($genType  x, $genType  y);
$pure half  dot($genHType x, $genHType y);
$pure float3 cross(float3 x, float3 y);
$pure half3  cross(half3  x, half3  y);
$pure $genType  normalize($genType  x);
$pure $genHType normalize($genHType x);
$pure $genType  faceforward($genType  N, $genType  I, $genType  Nref);
$pure $genHType faceforward($genHType N, $genHType I, $genHType Nref);
$pure $genType  reflect($genType  I, $genType  N);
$pure $genHType reflect($genHType I, $genHType N);
$pure $genType  refract($genType  I, $genType  N, float eta);
$pure $genHType refract($genHType I, $genHType N, half eta);

// 8.6 : Matrix Functions
$pure $squareMat  matrixCompMult($squareMat  x, $squareMat  y);
$pure $squareHMat matrixCompMult($squareHMat x, $squareHMat y);
$pure $es3 $mat   matrixCompMult($mat x, $mat y);
$pure $es3 $hmat  matrixCompMult($hmat x, $hmat y);

// 8.6 : Matrix Functions (GLSL 1.4, poly-filled by SkSL as needed)
$pure $squareMat  inverse($squareMat  m);
$pure $squareHMat inverse($squareHMat m);

// 8.6 : Matrix Functions (GLSL ES 3.0)
$pure $es3 float       determinant($squareMat m);
$pure $es3 half        determinant($squareHMat m);
$pure $es3 $squareMat  transpose($squareMat  m);
$pure $es3 $squareHMat transpose($squareHMat m);
$pure $es3 float2x3    transpose(float3x2 m);
$pure $es3 half2x3     transpose(half3x2  m);
$pure $es3 float2x4    transpose(float4x2 m);
$pure $es3 half2x4     transpose(half4x2  m);
$pure $es3 float3x2    transpose(float2x3 m);
$pure $es3 half3x2     transpose(half2x3  m);
$pure $es3 float3x4    transpose(float4x3 m);
$pure $es3 half3x4     transpose(half4x3  m);
$pure $es3 float4x2    transpose(float2x4 m);
$pure $es3 half4x2     transpose(half2x4  m);
$pure $es3 float4x3    transpose(float3x4 m);
$pure $es3 half4x3     transpose(half3x4  m);
$pure $es3 $squareMat  outerProduct($vec   c, $vec   r);
$pure $es3 $squareHMat outerProduct($hvec  c, $hvec  r);
$pure $es3 float2x3    outerProduct(float3 c, float2 r);
$pure $es3 half2x3     outerProduct(half3  c, half2  r);
$pure $es3 float3x2    outerProduct(float2 c, float3 r);
$pure $es3 half3x2     outerProduct(half2  c, half3  r);
$pure $es3 float2x4    outerProduct(float4 c, float2 r);
$pure $es3 half2x4     outerProduct(half4  c, half2  r);
$pure $es3 float4x2    outerProduct(float2 c, float4 r);
$pure $es3 half4x2     outerProduct(half2  c, half4  r);
$pure $es3 float3x4    outerProduct(float4 c, float3 r);
$pure $es3 half3x4     outerProduct(half4  c, half3  r);
$pure $es3 float4x3    outerProduct(float3 c, float4 r);
$pure $es3 half4x3     outerProduct(half3  c, half4  r);

// 8.7 : Vector Relational Functions
$pure $bvec lessThan($vec  x, $vec  y);
$pure $bvec lessThan($hvec x, $hvec y);
$pure $bvec lessThan($ivec x, $ivec y);
$pure $bvec lessThan($svec x, $svec y);
$pure $bvec lessThanEqual($vec  x, $vec  y);
$pure $bvec lessThanEqual($hvec x, $hvec y);
$pure $bvec lessThanEqual($ivec x, $ivec y);
$pure $bvec lessThanEqual($svec x, $svec y);
$pure $bvec greaterThan($vec  x, $vec  y);
$pure $bvec greaterThan($hvec x, $hvec y);
$pure $bvec greaterThan($ivec x, $ivec y);
$pure $bvec greaterThan($svec x, $svec y);
$pure $bvec greaterThanEqual($vec  x, $vec  y);
$pure $bvec greaterThanEqual($hvec x, $hvec y);
$pure $bvec greaterThanEqual($ivec x, $ivec y);
$pure $bvec greaterThanEqual($svec x, $svec y);
$pure $bvec equal($vec  x, $vec  y);
$pure $bvec equal($hvec x, $hvec y);
$pure $bvec equal($ivec x, $ivec y);
$pure $bvec equal($svec x, $svec y);
$pure $bvec equal($bvec x, $bvec y);
$pure $bvec notEqual($vec  x, $vec  y);
$pure $bvec notEqual($hvec x, $hvec y);
$pure $bvec notEqual($ivec x, $ivec y);
$pure $bvec notEqual($svec x, $svec y);
$pure $bvec notEqual($bvec x, $bvec y);

$pure $es3 $bvec lessThan($usvec x, $usvec y);
$pure $es3 $bvec lessThan($uvec x, $uvec y);
$pure $es3 $bvec lessThanEqual($uvec x, $uvec y);
$pure $es3 $bvec lessThanEqual($usvec x, $usvec y);
$pure $es3 $bvec greaterThan($uvec x, $uvec y);
$pure $es3 $bvec greaterThan($usvec x, $usvec y);
$pure $es3 $bvec greaterThanEqual($uvec x, $uvec y);
$pure $es3 $bvec greaterThanEqual($usvec x, $usvec y);
$pure $es3 $bvec equal($uvec x, $uvec y);
$pure $es3 $bvec equal($usvec x, $usvec y);
$pure $es3 $bvec notEqual($uvec x, $uvec y);
$pure $es3 $bvec notEqual($usvec x, $usvec y);

$pure bool  any($bvec x);
$pure bool  all($bvec x);
$pure $bvec not($bvec x);

// 8.9 : Fragment Processing Functions (GLSL ES 3.0)
$pure $es3 $genType  dFdx($genType p);
$pure $es3 $genType  dFdy($genType p);
$pure $es3 $genHType dFdx($genHType p);
$pure $es3 $genHType dFdy($genHType p);
$pure $es3 $genType  fwidth($genType p);
$pure $es3 $genHType fwidth($genHType p);


// SkSL utility functions

// The max() guards against division by zero when the incoming color is transparent black
$pure half4  unpremul(half4  color) { return half4 (color.rgb / max(color.a, 0.0001), color.a); }
$pure float4 unpremul(float4 color) { return float4(color.rgb / max(color.a, 0.0001), color.a); }

// Similar, but used for polar-space CSS colors
$export $pure half4 $unpremul_polar(half4 color) {
    return half4(color.r, color.gb / max(color.a, 0.0001), color.a);
}

// Convert RGBA -> HSLA (including unpremul).
//
// Based on work by Sam Hocevar, Emil Persson, and Ian Taylor [1][2][3].  High-level ideas:
//
//   - minimize the number of branches by sorting and computing the hue phase in parallel (vec4s)
//
//   - trade the third sorting branch for a potentially faster std::min and leaving 2nd/3rd
//     channels unsorted (based on the observation that swapping both the channels and the bias sign
//     has no effect under abs)
//
//   - use epsilon offsets for denominators, to avoid explicit zero-checks
//
// An additional trick we employ is deferring premul->unpremul conversion until the very end: the
// alpha factor gets naturally simplified for H and S, and only L requires a dedicated unpremul
// division (so we trade three divs for one).
//
// [1] http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv
// [2] http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
// [3] http://www.chilliant.com/rgb2hsv.html

$export $pure half4 $rgb_to_hsl(half3 c, half a) {
    half4 p = (c.g < c.b) ? half4(c.bg, -1,  2/3.0)
                          : half4(c.gb,  0, -1/3.0);
    half4 q = (c.r < p.x) ? half4(p.x, c.r, p.yw)
                          : half4(c.r, p.x, p.yz);

    // q.x  -> max channel value
    // q.yz -> 2nd/3rd channel values (unsorted)
    // q.w  -> bias value dependent on max channel selection

    const half kEps = 0.0001;
    half pmV = q.x;
    half pmC = pmV - min(q.y, q.z);
    half pmL = pmV - pmC * 0.5;
    half   H = abs(q.w + (q.y - q.z) / (pmC * 6 + kEps));
    half   S = pmC / (a + kEps - abs(pmL * 2 - a));
    half   L = pmL / (a + kEps);

    return half4(H, S, L, a);
}

// Convert HSLA -> RGBA (including clamp and premul).
//
// Based on work by Sam Hocevar, Emil Persson, and Ian Taylor [1][2][3].
//
// [1] http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv
// [2] http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
// [3] http://www.chilliant.com/rgb2hsv.html

$export $pure half3 $hsl_to_rgb(half3 hsl) {
    half      C = (1 - abs(2 * hsl.z - 1)) * hsl.y;
    half3     p = hsl.xxx + half3(0, 2/3.0, 1/3.0);
    half3     q = saturate(abs(fract(p) * 6 - 3) - 1);

    return (q - 0.5) * C + hsl.z;
}

$export $pure half4 $hsl_to_rgb(half3 hsl, half a) {
    return saturate(half4($hsl_to_rgb(hsl) * a, a));
}

// Color conversion functions used in gradient interpolation, based on
// https://www.w3.org/TR/css-color-4/#color-conversion-code
// TODO(skia:13108): For all of these, we can eliminate any linear math at the beginning
// (by removing the corresponding linear math at the end of the CPU code).
$export $pure half3 $css_lab_to_xyz(half3 lab) {
    const half k = 24389 / 27.0;
    const half e = 216 / 24389.0;

    half3 f;
    f[1] = (lab[0] + 16) / 116;
    f[0] = (lab[1] / 500) + f[1];
    f[2] = f[1] - (lab[2] / 200);

    half3 f_cubed = pow(f, half3(3));

    half3 xyz = half3(
        f_cubed[0] > e ? f_cubed[0] : (116 * f[0] - 16) / k,
        lab[0] > k * e ? f_cubed[1] : lab[0] / k,
        f_cubed[2] > e ? f_cubed[2] : (116 * f[2] - 16) / k
    );

    const half3 D50 = half3(0.3457 / 0.3585, 1.0, (1.0 - 0.3457 - 0.3585) / 0.3585);
    return xyz * D50;
}

// Skia stores all polar colors with hue in the first component, so this "LCH -> Lab" transform
// actually takes "HCL". This is also used to do the same polar transform for OkHCL to OkLAB.
// See similar comments & logic in SkGradientShaderBase.cpp.
$pure half3 $css_hcl_to_lab(half3 hcl) {
    return half3(
        hcl[2],
        hcl[1] * cos(radians(hcl[0])),
        hcl[1] * sin(radians(hcl[0]))
    );
}

$export $pure half3 $css_hcl_to_xyz(half3 hcl) {
    return $css_lab_to_xyz($css_hcl_to_lab(hcl));
}

$export $pure half3 $css_oklab_to_linear_srgb(half3 oklab) {
    half l_ = oklab.x + 0.3963377774 * oklab.y + 0.2158037573 * oklab.z,
         m_ = oklab.x - 0.1055613458 * oklab.y - 0.0638541728 * oklab.z,
         s_ = oklab.x - 0.0894841775 * oklab.y - 1.2914855480 * oklab.z;

    half l = l_*l_*l_,
         m = m_*m_*m_,
         s = s_*s_*s_;

    return half3(
        +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
        -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
        -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s
    );
}

$export $pure half3 $css_okhcl_to_linear_srgb(half3 okhcl) {
    return $css_oklab_to_linear_srgb($css_hcl_to_lab(okhcl));
}

$export $pure half3 $css_oklab_gamut_map_to_linear_srgb(half3 oklab) {
    // Constants for the normal vector of the plane formed by white, black, and
    // the specified vertex of the gamut.
    const half2 normal_R = half2(0.409702, -0.912219);
    const half2 normal_M = half2(-0.397919, -0.917421);
    const half2 normal_B = half2(-0.906800, 0.421562);
    const half2 normal_C = half2(-0.171122, 0.985250);
    const half2 normal_G = half2(0.460276, 0.887776);
    const half2 normal_Y = half2(0.947925, 0.318495);

    // For the triangles formed by white (W) or black (K) with the vertices
    // of Yellow and Red (YR), Red and Magenta (RM), etc, the constants to be
    // used to compute the intersection of a line of constant hue and luminance
    // with that plane.
    const half  c0_YR = 0.091132;
    const half2 cW_YR = half2(0.070370, 0.034139);
    const half2 cK_YR = half2(0.018170, 0.378550);
    const half  c0_RM = 0.113902;
    const half2 cW_RM = half2(0.090836, 0.036251);
    const half2 cK_RM = half2(0.226781, 0.018764);
    const half  c0_MB = 0.161739;
    const half2 cW_MB = half2(-0.008202, -0.264819);
    const half2 cK_MB = half2( 0.187156, -0.284304);
    const half  c0_BC = 0.102047;
    const half2 cW_BC = half2(-0.014804, -0.162608);
    const half2 cK_BC = half2(-0.276786,  0.004193);
    const half  c0_CG = 0.092029;
    const half2 cW_CG = half2(-0.038533, -0.001650);
    const half2 cK_CG = half2(-0.232572, -0.094331);
    const half  c0_GY = 0.081709;
    const half2 cW_GY = half2(-0.034601, -0.002215);
    const half2 cK_GY = half2( 0.012185,  0.338031);

    half2 ab = oklab.yz;

    // Find the planes to intersect with and set the constants based on those
    // planes.
    half c0;
    half2 cW;
    half2 cK;
    if (dot(ab, normal_R) < 0.0) {
        if (dot(ab, normal_G) < 0.0) {
            if (dot(ab, normal_C) < 0.0) {
                c0 = c0_BC; cW = cW_BC; cK = cK_BC;
            } else {
                c0 = c0_CG; cW = cW_CG; cK = cK_CG;
            }
        } else {
            if (dot(ab, normal_Y) < 0.0) {
                c0 = c0_GY; cW = cW_GY; cK = cK_GY;
            } else {
                c0 = c0_YR; cW = cW_YR; cK = cK_YR;
            }
        }
    } else {
        if (dot(ab, normal_B) < 0.0) {
            if (dot(ab, normal_M) < 0.0) {
                c0 = c0_RM; cW = cW_RM; cK = cK_RM;
            } else {
                c0 = c0_MB; cW = cW_MB; cK = cK_MB;
            }
        } else {
            c0 = c0_BC; cW = cW_BC; cK = cK_BC;
        }
    }

    // Perform the intersection.
    half alpha = 1.0;

    // Intersect with the plane with white.
    half w_denom = dot(cW, ab);
    if (w_denom > 0.0) {
        half one_minus_L = 1.0 - oklab.r;
        half w_num = c0*one_minus_L;
        if (w_num < w_denom) {
            alpha = min(alpha, w_num / w_denom);
        }
    }

    // Intersect with the plane with black.
    half k_denom = dot(cK, ab);
    if (k_denom > 0.0) {
        half L = oklab.r;
        half k_num = c0*L;
        if (k_num < k_denom) {
            alpha = min(alpha,  k_num / k_denom);
        }
    }

    // Attenuate the ab coordinate by alpha.
    oklab.yz *= alpha;

    return $css_oklab_to_linear_srgb(oklab);
}

$export $pure half3 $css_okhcl_gamut_map_to_linear_srgb(half3 okhcl) {
    return $css_oklab_gamut_map_to_linear_srgb($css_hcl_to_lab(okhcl));
}

// TODO(skia:13108): Use our optimized version (though it has different range)
// Doing so might require fixing (re-deriving?) the math for the HWB version below
$export $pure half3 $css_hsl_to_srgb(half3 hsl) {
    hsl.x = mod(hsl.x, 360);
    if (hsl.x < 0) {
        hsl.x += 360;
    }

    hsl.yz /= 100;

    half3 k = mod(half3(0, 8, 4) + hsl.x/30, 12);
    half a = hsl.y * min(hsl.z, 1 - hsl.z);
    return hsl.z - a * clamp(min(k - 3, 9 - k), -1, 1);
}

$export $pure half3 $css_hwb_to_srgb(half3 hwb) {
    half3 rgb;
    hwb.yz /= 100;
    if (hwb.y + hwb.z >= 1) {
        // Emit grayscale
        rgb = half3(hwb.y / (hwb.y + hwb.z));
    } else {
        rgb = $css_hsl_to_srgb(half3(hwb.x, 100, 50));
        rgb *= (1 - hwb.y - hwb.z);
        rgb += hwb.y;
    }
    return rgb;
}

/*
 * The actual output color space of this function depends on the input color space
 * (it might be sRGB, linear sRGB, or linear XYZ). The actual space is what's stored
 * in the gradient/SkColor4fXformer's fIntermediateColorSpace.
 */
$export $pure half4 $interpolated_to_rgb_unpremul(half4 color, int colorSpace, int doUnpremul) {
    const int kDestination   = 0;
    const int kSRGBLinear    = 1;
    const int kLab           = 2;
    const int kOKLab         = 3;
    const int kOKLabGamutMap = 4;
    const int kLCH           = 5;
    const int kOKLCH         = 6;
    const int kOKLCHGamutMap = 7;
    const int kSRGB          = 8;
    const int kHSL           = 9;
    const int kHWB           = 10;

    if (bool(doUnpremul)) {
        switch (colorSpace) {
            case kLab:
            case kOKLab:
            case kOKLabGamutMap: color = unpremul(color); break;
            case kLCH:
            case kOKLCH:
            case kOKLCHGamutMap:
            case kHSL:
            case kHWB: color = $unpremul_polar(color); break;
        }
    }
    switch (colorSpace) {
        case kLab:           color.rgb = $css_lab_to_xyz(color.rgb); break;
        case kOKLab:         color.rgb = $css_oklab_to_linear_srgb(color.rgb); break;
        case kOKLabGamutMap: color.rgb = $css_oklab_gamut_map_to_linear_srgb(color.rgb); break;
        case kLCH:           color.rgb = $css_hcl_to_xyz(color.rgb); break;
        case kOKLCH:         color.rgb = $css_okhcl_to_linear_srgb(color.rgb); break;
        case kOKLCHGamutMap: color.rgb = $css_okhcl_gamut_map_to_linear_srgb(color.rgb); break;
        case kHSL:           color.rgb = $css_hsl_to_srgb(color.rgb); break;
        case kHWB:           color.rgb = $css_hwb_to_srgb(color.rgb); break;
    }
    return color;
}

[ Dauer der Verarbeitung: 0.28 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge