////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

<languageVersion : 1.0;>
kernel Color
<   namespace : "Flame";
    vendor : "Adobe";
    version : 1;
    description : "Color blend mode";
>
{
    input image4 dst;
    input image4 src;
    output pixel4 result;

    // PB bytecode can't do functions, use macros to define common functions
    // gets the max number out of the three
    #define max3( x, y, z ) ( max((x), max((y), (z))) )
    // gets the min number out of the three
    #define min3( x, y, z ) ( min((x), min((y), (z))) )

    // gets the max number out of the three elements in a vector
    #define max3v(C) ( max3((C.x), (C.y), (C.z)) )
    // gets the min number out of the three elements in a vector
    #define min3v(C) ( min3((C.x), (C.y), (C.z)) )

    // Sat - returns float, takes in a pixel3, or pixel4
    #define saturation(C) ( (max3((C.r), (C.g), (C.b)) - min3((C.r), (C.g), (C.b))) )

    // Luminance - returns float, takes in a pixel3, or pixel4
    #define luminance(C) ( (((C.r) * 0.3) + ((C.g) * 0.59) + ((C.b) * 0.11)) )

    void
    evaluatePixel()
    {
        pixel4 a = sampleNearest(dst,outCoord()); // cb
        pixel4 b = sampleNearest(src,outCoord()); // cs
        
        // remove premultiplied (srcCP/srcA, dstCP/dstA)
        pixel3 cb = a.rgb;
        pixel3 cs = b.rgb;
        if (a.a > 0.0) {
            cb.rgb = a.rgb / a.a;
        }
        if (b.a > 0.0) {
            cs.rgb = b.rgb / b.a;
        }
        
        // dstA' = (1-srcA)*dstA + srcA
        result.a = (1.0-b.a)*a.a + b.a;
        
        // adjustment -> adjustedcs
        float3 adjVec = (cb - cs);
        float adjustment = luminance(adjVec);
        float3 adjustedcs = cs + adjustment;
        
        // Blend()
        
        /* --------------------------------------------------------
         * void clipcolor(inout float3 color)
         *     clips color.
         * input and output float3 color_cl
         * 
         * -------------------------------------------------------- */
        float3 color_cl = adjustedcs;
        float lum_cl = luminance(color_cl);
        float3 lumVec = float3(lum_cl, lum_cl, lum_cl);
        float mini = min3v(color_cl);
        float maxi = max3v(color_cl);
        if (mini < 0.0) {
            mini = lum_cl - mini;
            // max(..., 0.0000001) prevents divide by 0
            color_cl = lumVec + (color_cl - lumVec)*lum_cl/max(mini, 0.0000001);
        }
        if (maxi > 1.0) {
            maxi = maxi - lum_cl;
            // max(..., 0.0000001) prevents divide by 0
            color_cl = lumVec + (color_cl - lumVec)*(1.0 - lum_cl)/max(maxi, 0.0000001);
        }
        // end clipcolor - result: color_cl ---------------------- //
               
        // dstCP' = (1-srcA)*dstCP + (1-dstA)*srcCP + srcA*dstA*Blend(srcCP/srcA, dstCP/dstA)
        result.rgb = ((1.0-b.a)*a.rgb) + ((1.0-a.a)*b.rgb) + b.a*a.a*color_cl.rgb;
    }
}