mmf
Class MMF_ExtendedColorMerge

Object
  extended by common:Generic
      extended by common:ColorMerge
          extended by common:DefaultColorMerge
              extended by mmf:MMF_ExtendedColorMerge

class 
DefaultColorMerge:MMF_ExtendedColorMerge

Extended colour merges.
David Makin May 2008
Anyone interested in merge modes may like to look here:
http://www.pegtop.net/delphi/articles/blendmodes/


Ultra Fractal Source

Toggle UF Source Code Display

 class MMF_ExtendedColorMerge(common.ulb:DefaultColorMerge) {
 ;
 ; Extended colour merges.<br>
 ; David Makin May 2008<br>
 ;
 ; Anyone interested in merge modes may like to look here:<br>
 ; http://www.pegtop.net/delphi/articles/blendmodes/<br>
 public:
 
   ; @param pparent the parent, generally "this" for the parent, or zero
   func MMF_ExtendedColorMerge(Generic pparent)
     DefaultColorMerge.DefaultColorMerge(pparent)
   endfunc
 
   ; @param pbottom the base color
   ; @param ptop the top color
   ; @return merged color
   color func Merge(color pbottom, color ptop)
 
     if @p_modeselect=="MMF Merge Modes"
 
     if @clamp
       float r = red(ptop)
       float g = green(ptop)
       float b = blue(ptop)
       if r<0.0
         r = 0.0
       elseif r>1.0
         r = 1.0
       endif
       if g<0.0
         g = 0.0
       elseif g>1.0
         g = 1.0
       endif
       if b<0.0
         b = 0.0
       elseif b>1.0
         b = 1.0
       endif
       ptop = rgba(r,g,b,alpha(ptop))
       r = red(pbottom)
       g = green(pbottom)
       b = blue(pbottom)
       if r<0.0
         r = 0.0
       elseif r>1.0
         r = 1.0
       endif
       if g<0.0
         g = 0.0
       elseif g>1.0
         g = 1.0
       endif
       if b<0.0
         b = 0.0
       elseif b>1.0
         b = 1.0
       endif
       pbottom = rgba(r,g,b,alpha(pbottom))
     endif
 
     if @p_mmfmergemode=="Exclusion"
       return rgba(red(pbottom) + red(ptop) - 2*red(pbottom)*red(ptop), \
                   green(pbottom) + green(ptop) - 2*green(pbottom)*green(ptop), \
                   blue(pbottom) + blue(ptop) - 2*blue(pbottom)*blue(ptop), \
                   alpha(ptop) )
     elseif @p_mmfmergemode=="Fade Down"
       return rgba( red(ptop) * (1 - red(ptop) + red(pbottom)), \
                    green(ptop) * (1 - green(ptop) + green(pbottom)), \
                    blue(ptop) * (1 - blue(ptop) + blue(pbottom)), alpha(ptop) )
     elseif @p_mmfmergemode=="Fade Up"
       return rgba(red(pbottom) + red(ptop)*(red(ptop) - red(pbottom)), \
                   green(pbottom) + green(ptop)*(green(ptop) - green(pbottom)), \
                   blue(pbottom) + blue(ptop)*(blue(ptop) - blue(pbottom)), \
                   alpha(ptop) )
     elseif @p_mmfmergemode=="Contrast Down"
       return rgba( 0.5 + red(ptop)*(red(pbottom) - 0.5), \
                    0.5 + green(ptop)*(green(pbottom) - 0.5), \
                    0.5 + blue(ptop)*(blue(pbottom) - 0.5), alpha(ptop) )
     elseif @p_mmfmergemode=="Contrast Up"
       float r = red(pbottom)
       float g = green(pbottom)
       float b = blue(pbottom)
       if r<0.5
         r = r - 2.0*red(ptop)*r*(0.5 - r)
       else
         r = r + 2.0*red(ptop)*(1.0 - r)*(r - 0.5)
       endif
       if g<0.5
         g = g - 2.0*green(ptop)*g*(0.5 - g)
       else
         g = g + 2.0*green(ptop)*(1.0 - g)*(g - 0.5)
       endif
       if b<0.5
         b = b - 2.0*blue(ptop)*b*(0.5 - b)
       else
         b = b + 2.0*blue(ptop)*(1.0 - b)*(b - 0.5)
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Dodge"
 ; Here we clamp the maximum returned to 1.0 because of the special case
 ; when the color channel in ptop is one (or more).
       float r = 1.0 - red(ptop)
       float g = 1.0 - green(ptop)
       float b = 1.0 - blue(ptop)
       if red(pbottom)<=0
         r = 0.0
       elseif r<=0.0
         r = 1.0
       else
         r = red(pbottom)/r
         if r>1.0
           r = 1.0
         endif
       endif
       if green(pbottom)<=0
         g = 0
       elseif g<=0.0
         g = 1.0
       else
         g = green(pbottom)/g
         if g>1.0
           g = 1.0
         endif
       endif
       if blue(pbottom)<=0
         b = 0
       elseif b<=0.0
         b = 1.0
       else
         b = blue(pbottom)/b
         if b>1.0
           b = 1.0
         endif
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Burn"
 ; Here we clamp the minimum returned to 0 because of the special case
 ; when the color channel in ptop is zero (or less).
       float r = red(ptop)
       float g = green(ptop)
       float b = blue(ptop)
       if r<=0.0
         r = 0.0
       else
         r = 1.0 - (1.0 - red(pbottom))/r
         if r<0.0
           r = 0.0
         endif
       endif
       if g<=0.0
         g = 0.0
       else
         g = 1.0 - (1.0 - green(pbottom))/g
         if g<0.0
           g = 0.0
         endif
       endif
       if b<=0.0
         b = 0.0
       else
         b = 1.0 - (1.0 - blue(pbottom))/b
         if b<0.0
           b = 0.0
         endif
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Negation"
       return rgba( 1.0 - abs(1.0 - red(ptop) - red(pbottom)), \
                    1.0 - abs(1.0 - green(ptop) - green(pbottom)), \
                    1.0 - abs(1.0 - blue(ptop) - blue(pbottom)), alpha(ptop) )
     elseif @p_mmfmergemode=="Reflect"
 ; Here we clamp the maximum returned to 1.0 because of the special case
 ; when the color channel in ptop is one (or more).
       float r = 1.0 - red(ptop)
       float g = 1.0 - green(ptop)
       float b = 1.0 - blue(ptop)
       if red(pbottom)<=0
         r = 0.0
       elseif r<=0.0
         r = 1.0
       else
         r = sqr(red(pbottom))/r
         if r>1.0
           r = 1.0
         endif
       endif
       if green(pbottom)<=0
         g = 0.0
       elseif g<=0.0
         g = 1.0
       else
         g = sqr(green(pbottom))/g
         if g>1.0
           g = 1.0
         endif
       endif
       if blue(pbottom)<=0
         b = 0.0
       elseif b<=0.0
         b = 1.0
       else
         b = sqr(blue(pbottom))/b
         if b>1.0
           b = 1.0
         endif
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Freeze"
 ; Here we clamp the minimum returned to 0 because of the special case
 ; when the color channel in ptop is zero (or less).
       float r = red(ptop)
       float g = green(ptop)
       float b = blue(ptop)
       if r<=0.0
         r = 0.0
       else
         r = 1.0 - sqr(1.0 - red(pbottom))/r
         if r<0.0
           r = 0.0
         endif
       endif
       if g<=0.0
         g = 0.0
       else
         g = 1.0 - sqr(1.0 - green(pbottom))/g
         if g<0.0
           g = 0.0
         endif
       endif
       if b<=0.0
         b = 0.0
       else
         b = 1.0 - sqr(1.0 - blue(pbottom))/b
         if b<0.0
           b = 0.0
         endif
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Rev. Contrast Down"
       return rgba( 0.5 + (1.0 - red(ptop))*(red(pbottom) - 0.5), \
                    0.5 + (1.0 - green(ptop))*(green(pbottom) - 0.5), \
                    0.5 + (1.0 - blue(ptop))*(blue(pbottom) - 0.5), alpha(ptop) )
     elseif @p_mmfmergemode=="Rev. Contrast Up"
       float r = red(pbottom)
       float g = green(pbottom)
       float b = blue(pbottom)
       if r<0.5
         r = r - 2.0*(1.0 - red(ptop))*r*(0.5 - r)
       else
         r = r + 2.0*(1.0 - red(ptop))*(1.0 - r)*(r - 0.5)
       endif
       if g<0.5
         g = g - 2.0*(1.0 - green(ptop))*g*(0.5 - g)
       else
         g = g + 2.0*(1.0 - green(ptop))*(1.0 - g)*(g - 0.5)
       endif
       if b<0.5
         b = b - 2.0*(1.0 - blue(ptop))*b*(0.5 - b)
       else
         b = b + 2.0*(1.0 - blue(ptop))*(1.0 - b)*(b - 0.5)
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Fade"
       float r = red(ptop)
       float g = green(ptop)
       float b = blue(ptop)
       if r<0.5
         r = 2.0 * r * (0.5 - r + red(pbottom))
       else
         r = red(pbottom) + 2.0 * (r - 0.5)*(r - red(pbottom))
       endif
       if g<0.5
         g = 2.0 * g * (0.5 - g + green(pbottom))
       else
         g = green(pbottom) + 2.0 * (g - 0.5)*(g - green(pbottom))
       endif
       if b<0.5
         b = 2.0 * b * (0.5 - b + blue(pbottom))
       else
         b = blue(pbottom) + 2.0 * (b - 0.5)*(b - blue(pbottom))
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Reverse Fade"
       float r = red(ptop)
       float g = green(ptop)
       float b = blue(ptop)
       if r<0.5
         r = red(pbottom) + 2.0 * r * (r - red(pbottom))
       else
         r = red(pbottom) + 2.0 * (1.0 - r)*(r - red(pbottom))
       endif
       if g<0.5
         g = green(pbottom) + 2.0 * g * (g - green(pbottom))
       else
         g = green(pbottom) + 2.0 * (1.0 - g)*(g - green(pbottom))
       endif
       if b<0.5
         b = blue(pbottom) + 2.0 * b * (b - blue(pbottom))
       else
         b = blue(pbottom) + 2.0 * (1.0 - b)*(b - blue(pbottom))
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Contrast" || @p_mmfmergemode=="Reverse Contrast"
       float r1 = red(ptop)
       float g1 = green(ptop)
       float b1 = blue(ptop)
       if @p_mmfmergemode=="Reverse Contrast"
         r1 = 1.0 - r1
         g1 = 1.0 - g1
         b1 = 1.0 - b1
       endif
       if r1<0.5
         r1 = 0.5 + 2.0 * r1 * (red(pbottom) - 0.5)
       else
         r1 = 2.0 * (r1 - 0.5)
         float r = red(pbottom)
         if r<0.5
           r1 = r - 2.0*r1*r*(0.5 - r)
         else
           r1 = r + 2.0*r1*(1.0 - r)*(r - 0.5)
         endif
       endif
       if g1<0.5
         g1 = 0.5 + 2.0 * g1 * (green(pbottom) - 0.5)
       else
         g1 = 2.0 * (g1 - 0.5)
         float g = green(pbottom)
         if g<0.5
           g1 = g - 2.0*g1*g*(0.5 - g)
         else
           g1 = g + 2.0*g1*(1.0 - g)*(g - 0.5)
         endif
       endif
       if b1<0.5
         b1 = 0.5 + 2.0 * b1 * (blue(pbottom) - 0.5)
       else
         b1 = 2.0 * (b1 - 0.5)
         float b = blue(pbottom)
         if b<0.5
           b1 = b - 2.0*b1*b*(0.5 - b)
         else
           b1 = b + 2.0*b1*(1.0 - b)*(b - 0.5)
         endif
       endif
       return rgba(r1,g1,b1,alpha(ptop))
     elseif @p_mmfmergemode=="Quantize"
       int nr = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + red(ptop)) - 1.0)) - 1
       int ng = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + green(ptop)) - 1.0)) - 1
       int nb = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + blue(ptop)) - 1.0)) - 1
       return rgba(floor(red(pbottom)*(nr+0.999))/nr, \
                   floor(green(pbottom)*(ng+0.999))/ng, \
                   floor(blue(pbottom)*(nb+0.999))/nb,alpha(ptop))
     elseif @p_mmfmergemode=="Reverse Quantize"
       int nr = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - red(ptop)) - 1.0)) - 1
       int ng = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - green(ptop)) - 1.0)) - 1
       int nb = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - blue(ptop)) - 1.0)) - 1
       return rgba(floor(red(pbottom)*(nr+0.999))/nr, \
                   floor(green(pbottom)*(ng+0.999))/ng, \
                   floor(blue(pbottom)*(nb+0.999))/nb,alpha(ptop))
     elseif @p_mmfmergemode=="Gamma"
       return rgba(red(pbottom)^(@mingamma+(@maxgamma-@mingamma)*red(ptop)), \
                   green(pbottom)^(@mingamma+(@maxgamma-@mingamma)*green(ptop)), \
                   blue(pbottom)^(@mingamma+(@maxgamma-@mingamma)*blue(ptop)), \
                   alpha(ptop))
     elseif @p_mmfmergemode=="Inverse Gamma"
       return rgba(red(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*red(ptop))), \
                   green(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*green(ptop))), \
                   blue(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*blue(ptop))), \
                   alpha(ptop))
     elseif @p_mmfmergemode=="Reverse Gamma"
       return rgba(red(pbottom)^(@mingamma+(@maxgamma-@mingamma)*(1.0-red(ptop))), \
                   green(pbottom)^(@mingamma+(@maxgamma-@mingamma)*(1.0-green(ptop))), \
                   blue(pbottom)^(@mingamma+(@maxgamma-@mingamma)*(1.0-blue(ptop))), \
                   alpha(ptop))
     elseif @p_mmfmergemode=="Rev. Inv. Gamma"
       return rgba(red(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-red(ptop)))), \
                   green(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-green(ptop)))), \
                   blue(pbottom)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-blue(ptop)))), \
                   alpha(ptop))
     elseif @p_mmfmergemode=="Combined Gamma"
       float r = red(ptop)
       float g = green(ptop)
       float b = blue(ptop)
       if r<0.5
         r = red(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-red(ptop)))
       else
         r = red(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(red(ptop)-0.5)))
       endif
       if g<0.5
         g = green(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-green(ptop)))
       else
         g = green(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(green(ptop)-0.5)))
       endif
       if b<0.5
         b = blue(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-blue(ptop)))
       else
         b = blue(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(blue(ptop)-0.5)))
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Rev. Comb. Gamma"
       float r = red(ptop)
       float g = green(ptop)
       float b = blue(ptop)
       if r<0.5
         r = red(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-red(ptop))))
       else
         r = red(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(red(ptop)-0.5))
       endif
       if g<0.5
         g = green(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-green(ptop))))
       else
         g = green(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(green(ptop)-0.5))
       endif
       if b<0.5
         b = blue(pbottom)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-blue(ptop))))
       else
         b = blue(pbottom)^(@mingamma+2.0*(@maxgamma-@mingamma)*(blue(ptop)-0.5))
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Stamp"
       float r = red(pbottom) + 2.0*red(ptop) - 1.0
       float g = green(pbottom) + 2.0*green(ptop) - 1.0
       float b = blue(pbottom) + 2.0*blue(ptop) - 1.0
       if r<0.0
         r = 0.0
       elseif r>1.0
         r = 1.0
       endif
       if g<0.0
         g = 0.0
       elseif g>1.0
         g = 1.0
       endif
       if b<0.0
         b = 0.0
       elseif b>1.0
         b = 1.0
       endif
       return RGBA(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Soft Dodge"
       float r = red(pbottom)
       float g = green(pbottom)
       float b = blue(pbottom)
       if r<=0
         r = 0
       elseif r+red(ptop)<=1.0
         if red(ptop)>=1.0
           r = 1.0
         elseif (r = 0.5*r/(1.0 - red(ptop)))>1.0
           r = 1.0
         endif
       elseif (r = 1.0 - 0.5*(1.0 - red(ptop))/r)<0.0
         r =  0.0
       endif
       if g<=0
         g = 0
       elseif g+green(ptop)<=1.0
         if green(ptop)>=1.0
           g = 1.0
         elseif (g = 0.5*g/(1.0 - green(ptop)))>1.0
           g = 1.0
         endif
       elseif (g = 1.0 - 0.5*(1.0 - green(ptop))/g)<0.0
         g =  0.0
       endif
       if b<=0
         b = 0
       elseif b+blue(ptop)<=1.0
         if blue(ptop)>=1.0
           b = 1.0
         elseif (b = 0.5*b/(1.0 - blue(ptop)))>1.0
           b = 1.0
         endif
       elseif (b = 1.0 - 0.5*(1.0 - blue(ptop))/b)<0.0
         b =  0.0
       endif
       return RGBA(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Soft Burn"
       float r = red(ptop)
       float g = green(ptop)
       float b = blue(ptop)
       if r<=0
         r = 0
       elseif r+red(pbottom)<=1.0
         if red(pbottom)>=1.0
           r = 1.0
         elseif (r = 0.5*r/(1.0 - red(pbottom)))>1.0
           r = 1.0
         endif
       elseif (r = 1.0 - 0.5*(1.0 - red(pbottom))/r)<0.0
         r =  0.0
       endif
       if g<=0
         g = 0
       elseif g+green(pbottom)<=1.0
         if green(pbottom)>=1.0
           g = 1.0
         elseif (g = 0.5*g/(1.0 - green(pbottom)))>1.0
           g = 1.0
         endif
       elseif (g = 1.0 - 0.5*(1.0 - green(pbottom))/g)<0.0
         g =  0.0
       endif
       if b<=0
         b = 0
       elseif b+blue(pbottom)<=1.0
         if blue(pbottom)>=1.0
           b = 1.0
         elseif (b = 0.5*b/(1.0 - blue(pbottom)))>1.0
           b = 1.0
         endif
       elseif (b = 1.0 - 0.5*(1.0 - blue(pbottom))/b)<0.0
         b =  0.0
       endif
       return RGBA(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Inverse Dodge"
 ; Here we clamp the maximum returned to 1.0 because of the special case
 ; when the color channel in ptop is one (or more).
       float r = 1.0 - red(pbottom)
       float g = 1.0 - green(pbottom)
       float b = 1.0 - blue(pbottom)
       if red(ptop)<=0
         r = 0
       elseif r<=0.0
         r = 1.0
       else
         r = red(ptop)/r
         if r>1.0
           r = 1.0
         endif
       endif
       if green(ptop)<=0
         g = 0
       elseif g<=0.0
         g = 1.0
       else
         g = green(ptop)/g
         if g>1.0
           g = 1.0
         endif
       endif
       if blue(ptop)<=0
         b = 0
       elseif b<=0.0
         b = 1.0
       else
         b = blue(ptop)/b
         if b>1.0
           b = 1.0
         endif
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Inverse Burn"
 ; Here we clamp the minimum returned to 0 because of the special case
 ; when the color channel in ptop is zero (or less).
       float r = red(pbottom)
       float g = green(pbottom)
       float b = blue(pbottom)
       if r<=0.0
         r = 0.0
       else
         r = 1.0 - (1.0 - red(ptop))/r
         if r<0.0
           r = 0.0
         endif
       endif
       if g<=0.0
         g = 0.0
       else
         g = 1.0 - (1.0 - green(ptop))/g
         if g<0.0
           g = 0.0
         endif
       endif
       if b<=0.0
         b = 0.0
       else
         b = 1.0 - (1.0 - blue(ptop))/b
         if b<0.0
           b = 0.0
         endif
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Glow"
 ; Here we clamp the maximum returned to 1.0 because of the special case
 ; when the color channel in ptop is one (or more).
       float r = 1.0 - red(pbottom)
       float g = 1.0 - green(pbottom)
       float b = 1.0 - blue(pbottom)
       if red(ptop)<=0
         r = 0.0
       elseif r<=0.0
         r = 1.0
       else
         r = sqr(red(ptop))/r
         if r>1.0
           r = 1.0
         endif
       endif
       if green(ptop)<=0
         g = 0.0
       elseif g<=0.0
         g = 1.0
       else
         g = sqr(green(ptop))/g
         if g>1.0
           g = 1.0
         endif
       endif
       if blue(ptop)<=0
         b = 0.0
       elseif b<=0.0
         b = 1.0
       else
         b = sqr(blue(ptop))/b
         if b>1.0
           b = 1.0
         endif
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Heat"
 ; Here we clamp the minimum returned to 0 because of the special case
 ; when the color channel in ptop is zero (or less).
       float r = red(pbottom)
       float g = green(pbottom)
       float b = blue(pbottom)
       if r<=0.0
         r = 0.0
       else
         r = 1.0 - sqr(1.0 - red(ptop))/r
         if r<0.0
           r = 0.0
         endif
       endif
       if g<=0.0
         g = 0.0
       else
         g = 1.0 - sqr(1.0 - green(ptop))/g
         if g<0.0
           g = 0.0
         endif
       endif
       if b<=0.0
         b = 0.0
       else
         b = 1.0 - sqr(1.0 - blue(ptop))/b
         if b<0.0
           b = 0.0
         endif
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Fade Down"
       return rgba( red(pbottom) * (1 - red(pbottom) + red(ptop)), \
                    green(pbottom) * (1 - green(pbottom) + green(ptop)), \
                    blue(pbottom) * (1 - blue(pbottom) + blue(ptop)), alpha(ptop) )
     elseif @p_mmfmergemode=="Inv. Fade Up"
       return rgba(red(ptop) + red(pbottom)*(red(pbottom) - red(ptop)), \
                   green(ptop) + green(pbottom)*(green(pbottom) - green(ptop)), \
                   blue(ptop) + blue(pbottom)*(blue(pbottom) - blue(ptop)), \
                   alpha(ptop) )
     elseif @p_mmfmergemode=="Inv. Contrast Down"
       return rgba( 0.5 + red(pbottom)*(red(ptop) - 0.5), \
                    0.5 + green(pbottom)*(green(ptop) - 0.5), \
                    0.5 + blue(pbottom)*(blue(ptop) - 0.5), alpha(ptop) )
     elseif @p_mmfmergemode=="Inv. Contrast Up"
       float r = red(ptop)
       float g = green(ptop)
       float b = blue(ptop)
       if r<0.5
         r = r - 2.0*red(pbottom)*r*(0.5 - r)
       else
         r = r + 2.0*red(pbottom)*(1.0 - r)*(r - 0.5)
       endif
       if g<0.5
         g = g - 2.0*green(pbottom)*g*(0.5 - g)
       else
         g = g + 2.0*green(pbottom)*(1.0 - g)*(g - 0.5)
       endif
       if b<0.5
         b = b - 2.0*blue(pbottom)*b*(0.5 - b)
       else
         b = b + 2.0*blue(pbottom)*(1.0 - b)*(b - 0.5)
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Rev. Con. Down"
       return rgba( 0.5 + (1.0 - red(pbottom))*(red(ptop) - 0.5), \
                    0.5 + (1.0 - green(pbottom))*(green(ptop) - 0.5), \
                    0.5 + (1.0 - blue(pbottom))*(blue(ptop) - 0.5), alpha(ptop) )
     elseif @p_mmfmergemode=="Inv. Rev. Con. Up"
       float r = red(ptop)
       float g = green(ptop)
       float b = blue(ptop)
       if r<0.5
         r = r - 2.0*(1.0 - red(pbottom))*r*(0.5 - r)
       else
         r = r + 2.0*(1.0 - red(pbottom))*(1.0 - r)*(r - 0.5)
       endif
       if g<0.5
         g = g - 2.0*(1.0 - green(pbottom))*g*(0.5 - g)
       else
         g = g + 2.0*(1.0 - green(pbottom))*(1.0 - g)*(g - 0.5)
       endif
       if b<0.5
         b = b - 2.0*(1.0 - blue(pbottom))*b*(0.5 - b)
       else
         b = b + 2.0*(1.0 - blue(pbottom))*(1.0 - b)*(b - 0.5)
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Inverse Fade"
       float r = red(pbottom)
       float g = green(pbottom)
       float b = blue(pbottom)
       if r<0.5
         r = 2.0 * r * (0.5 - r + red(ptop))
       else
         r = red(ptop) + 2.0 * (r - 0.5)*(r - red(ptop))
       endif
       if g<0.5
         g = 2.0 * g * (0.5 - g + green(ptop))
       else
         g = green(ptop) + 2.0 * (g - 0.5)*(g - green(ptop))
       endif
       if b<0.5
         b = 2.0 * b * (0.5 - b + blue(ptop))
       else
         b = blue(ptop) + 2.0 * (b - 0.5)*(b - blue(ptop))
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Rev. Fade"
       float r = red(pbottom)
       float g = green(pbottom)
       float b = blue(pbottom)
       if r<0.5
         r = red(ptop) + 2.0 * r * (r - red(ptop))
       else
         r = red(ptop) + 2.0 * (1.0 - r)*(r - red(ptop))
       endif
       if g<0.5
         g = green(ptop) + 2.0 * g * (g - green(ptop))
       else
         g = green(ptop) + 2.0 * (1.0 - g)*(g - green(ptop))
       endif
       if b<0.5
         b = blue(ptop) + 2.0 * b * (b - blue(ptop))
       else
         b = blue(ptop) + 2.0 * (1.0 - b)*(b - blue(ptop))
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Inverse Contrast" \
            || @p_mmfmergemode=="Inv. Rev. Contrast"
       float r1 = red(pbottom)
       float g1 = green(pbottom)
       float b1 = blue(pbottom)
       if @p_mmfmergemode=="Inv. Rev. Contrast"
         r1 = 1.0 - r1
         g1 = 1.0 - g1
         b1 = 1.0 - b1
       endif
       if r1<0.5
         r1 = 0.5 + 2.0 * r1 * (red(ptop) - 0.5)
       else
         r1 = 2.0 * (r1 - 0.5)
         float r = red(ptop)
         if r<0.5
           r1 = r - 2.0*r1*r*(0.5 - r)
         else
           r1 = r + 2.0*r1*(1.0 - r)*(r - 0.5)
         endif
       endif
       if g1<0.5
         g1 = 0.5 + 2.0 * g1 * (green(ptop) - 0.5)
       else
         g1 = 2.0 * (g1 - 0.5)
         float g = green(ptop)
         if g<0.5
           g1 = g - 2.0*g1*g*(0.5 - g)
         else
           g1 = g + 2.0*g1*(1.0 - g)*(g - 0.5)
         endif
       endif
       if b1<0.5
         b1 = 0.5 + 2.0 * b1 * (blue(ptop) - 0.5)
       else
         b1 = 2.0 * (b1 - 0.5)
         float b = blue(ptop)
         if b<0.5
           b1 = b - 2.0*b1*b*(0.5 - b)
         else
           b1 = b + 2.0*b1*(1.0 - b)*(b - 0.5)
         endif
       endif
       return rgba(r1,g1,b1,alpha(ptop))
     elseif @p_mmfmergemode=="Inverse Quantize"
       int nr = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + red(pbottom)) - 1.0)) - 1
       int ng = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + green(pbottom)) - 1.0)) - 1
       int nb = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + blue(pbottom)) - 1.0)) - 1
       return rgba(floor(red(ptop)*(nr+0.999))/nr, \
                   floor(green(ptop)*(ng+0.999))/ng, \
                   floor(blue(ptop)*(nb+0.999))/nb,alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Rev. Quantize"
       int nr = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - red(pbottom)) - 1.0)) - 1
       int ng = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - green(pbottom)) - 1.0)) - 1
       int nb = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - blue(pbottom)) - 1.0)) - 1
       return rgba(floor(red(ptop)*(nr+0.999))/nr, \
                   floor(green(ptop)*(ng+0.999))/ng, \
                   floor(blue(ptop)*(nb+0.999))/nb,alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Gamma"
       return rgba(red(ptop)^(@mingamma+(@maxgamma-@mingamma)*red(pbottom)), \
                   green(ptop)^(@mingamma+(@maxgamma-@mingamma)*green(pbottom)), \
                   blue(ptop)^(@mingamma+(@maxgamma-@mingamma)*blue(pbottom)), \
                   alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Inverse Gamma"
       return rgba(red(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*red(pbottom))), \
                   green(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*green(pbottom))), \
                   blue(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*blue(pbottom))), \
                   alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Reverse Gamma"
       return rgba(red(ptop)^(@mingamma+(@maxgamma-@mingamma)*(1.0-red(pbottom))), \
                   green(ptop)^(@mingamma+(@maxgamma-@mingamma)*(1.0-green(pbottom))), \
                   blue(ptop)^(@mingamma+(@maxgamma-@mingamma)*(1.0-blue(pbottom))), \
                   alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Rev. Inv. Gamma"
       return rgba(red(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-red(pbottom)))), \
                   green(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-green(pbottom)))), \
                   blue(ptop)^(1.0/(@mingamma+(@maxgamma-@mingamma)*(1.0-blue(pbottom)))), \
                   alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Combined Gamma"
       float r = red(pbottom)
       float g = green(pbottom)
       float b = blue(pbottom)
       if r<0.5
         r = red(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-r))
       else
         r = red(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(r-0.5)))
       endif
       if g<0.5
         g = green(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-g))
       else
         g = green(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(g-0.5)))
       endif
       if b<0.5
         b = blue(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-b))
       else
         b = blue(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(b-0.5)))
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Rev. Comb. Gamma"
       float r = red(pbottom)
       float g = green(pbottom)
       float b = blue(pbottom)
       if r<0.5
         r = red(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-r)))
       else
         r = red(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(r-0.5))
       endif
       if g<0.5
         g = green(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-g)))
       else
         g = green(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(g-0.5))
       endif
       if b<0.5
         b = blue(ptop)^(1.0/(@mingamma+2.0*(@maxgamma-@mingamma)*(0.5-b)))
       else
         b = blue(ptop)^(@mingamma+2.0*(@maxgamma-@mingamma)*(b-0.5))
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Inverse Stamp"
       float r = red(ptop) + 2.0*red(pbottom) - 1.0
       float g = green(ptop) + 2.0*green(pbottom) - 1.0
       float b = blue(ptop) + 2.0*blue(pbottom) - 1.0
       if r<0.0
         r = 0.0
       elseif r>1.0
         r = 1.0
       endif
       if g<0.0
         g = 0.0
       elseif g>1.0
         g = 1.0
       endif
       if b<0.0
         b = 0.0
       elseif b>1.0
         b = 1.0
       endif
       return RGBA(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Brightness (Yiq)"
       float btop = 0.299*red(ptop) + 0.587*green(ptop) + 0.114*blue(ptop)
       float bbtm = 0.299*red(pbottom) + 0.587*green(pbottom) \
                    + 0.114*blue(pbottom)
       if bbtm==0
         return RGBA(btop,btop,btop,alpha(ptop))
       else
         pbottom = pbottom*(btop/bbtm)
         return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop))
       endif
     elseif @p_mmfmergemode=="Colour (Inverse Yiq)"
       float btop = 0.299*red(ptop) + 0.587*green(ptop) + 0.114*blue(ptop)
       float bbtm = 0.299*red(pbottom) + 0.587*green(pbottom) \
                    + 0.114*blue(pbottom)
       if btop==0
         return RGBA(bbtm,bbtm,bbtm,alpha(ptop))
       else
         pbottom = ptop*(bbtm/btop)
         return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop))
       endif
     elseif @p_mmfmergemode=="Brightness (Custom)"
       float btop = (@redlvl*red(ptop) + @greenlvl*green(ptop) \
                     + @bluelvl*blue(ptop))/(@redlvl + @greenlvl +@bluelvl)
       float bbtm = (@redlvl*red(pbottom) + @greenlvl*green(pbottom) \
                     + @bluelvl*blue(pbottom))/(@redlvl + @greenlvl +@bluelvl)
       if bbtm==0
         return RGBA(btop,btop,btop,alpha(ptop))
       else
         pbottom = pbottom*(btop/bbtm)
         return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop))
       endif
     elseif @p_mmfmergemode=="Colour (Custom)"
       float btop = (@redlvl*red(ptop) + @greenlvl*green(ptop) \
                     + @bluelvl*blue(ptop))/(@redlvl + @greenlvl +@bluelvl)
       float bbtm = (@redlvl*red(pbottom) + @greenlvl*green(pbottom) \
                     + @bluelvl*blue(pbottom))/(@redlvl + @greenlvl +@bluelvl)
       if btop==0
         return RGBA(bbtm,bbtm,bbtm,alpha(ptop))
       else
         pbottom = ptop*(bbtm/btop)
         return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop))
       endif
     elseif @p_mmfmergemode=="Pin Light"
       float r = red(ptop)
       float g = green(ptop)
       float b = blue(ptop)
       if (r>=0.5 && r<red(pbottom)) || (r<0.5 && r>red(pbottom))
         r = red(pbottom)
       endif
       if (g>=0.5 && g<green(pbottom)) || (g<0.5 && g>green(pbottom))
         g = green(pbottom)
       endif
       if (b>=0.5 && b<blue(pbottom)) || (b<0.5 && b>blue(pbottom))
         b = blue(pbottom)
       endif
       return RGBA(r, g, b, alpha(ptop))
     elseif @p_mmfmergemode=="Reverse Pin Light"
       float r = red(ptop)
       float g = green(ptop)
       float b = blue(ptop)
       if (r>=0.5 && r>red(pbottom)) || (r<0.5 && r<red(pbottom))
         r = red(pbottom)
       endif
       if (g>=0.5 && g>green(pbottom)) || (g<0.5 && g<green(pbottom))
         g = green(pbottom)
       endif
       if (b>=0.5 && b>blue(pbottom)) || (b<0.5 && b<blue(pbottom))
         b = blue(pbottom)
       endif
       return RGBA(r, g, b, alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Pin Light"
       float r = red(pbottom)
       float g = green(pbottom)
       float b = blue(pbottom)
       if (r>=0.5 && r<red(ptop)) || (r<0.5 && r>red(ptop))
         r = red(ptop)
       endif
       if (g>=0.5 && g<green(ptop)) || (g<0.5 && g>green(ptop))
         g = green(ptop)
       endif
       if (b>=0.5 && b<blue(ptop)) || (b<0.5 && b>blue(ptop))
         b = blue(ptop)
       endif
       return RGBA(r, g, b, alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Rev. Pin Light"
       float r = red(pbottom)
       float g = green(pbottom)
       float b = blue(pbottom)
       if (r>=0.5 && r>red(ptop)) || (r<0.5 && r<red(ptop))
         r = red(ptop)
       endif
       if (g>=0.5 && g>green(ptop)) || (g<0.5 && g<green(ptop))
         g = green(ptop)
       endif
       if (b>=0.5 && b>blue(ptop)) || (b<0.5 && b<blue(ptop))
         b = blue(ptop)
       endif
       return RGBA(r, g, b, alpha(ptop))
     elseif @p_mmfmergemode=="Lighten (Yiq)"
       float btop = 0.299*red(ptop) + 0.587*green(ptop) + 0.114*blue(ptop)
       float bbtm = 0.299*red(pbottom) + 0.587*green(pbottom) \
                    + 0.114*blue(pbottom)
       if btop>bbtm
         if bbtm==0
           return RGBA(btop,btop,btop,alpha(ptop))
         else
           pbottom = pbottom*(btop/bbtm)
         endif
       endif
       return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop))
     elseif @p_mmfmergemode=="Darken (Yiq)"
       float btop = 0.299*red(ptop) + 0.587*green(ptop) + 0.114*blue(ptop)
       float bbtm = 0.299*red(pbottom) + 0.587*green(pbottom) \
                    + 0.114*blue(pbottom)
       if btop<bbtm
         pbottom = pbottom*(btop/bbtm)
       endif
       return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop))
     elseif @p_mmfmergemode=="Pin (Yiq)"
       float btop = 0.299*red(ptop) + 0.587*green(ptop) + 0.114*blue(ptop)
       float bbtm = 0.299*red(pbottom) + 0.587*green(pbottom) \
                    + 0.114*blue(pbottom)
       if (btop>=0.5 && btop>bbtm) || (btop<0.5 && btop<bbtm)
         if bbtm==0
           return RGBA(btop,btop,btop,alpha(ptop))
         else
           pbottom = pbottom*(btop/bbtm)
         endif
       endif
       return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop))
     elseif @p_mmfmergemode=="Reverse Pin (Yiq)"
       float btop = 0.299*red(ptop) + 0.587*green(ptop) + 0.114*blue(ptop)
       float bbtm = 0.299*red(pbottom) + 0.587*green(pbottom) \
                    + 0.114*blue(pbottom)
       if (btop>=0.5 && btop<bbtm) || (btop<0.5 && btop>bbtm)
         if bbtm==0
           return RGBA(btop,btop,btop,alpha(ptop))
         else
           pbottom = pbottom*(btop/bbtm)
         endif
       endif
       return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Pin (Yiq)"
       float btop = 0.299*red(ptop) + 0.587*green(ptop) + 0.114*blue(ptop)
       float bbtm = 0.299*red(pbottom) + 0.587*green(pbottom) \
                    + 0.114*blue(pbottom)
       if (bbtm>=0.5 && btop>bbtm) || (bbtm<0.5 && btop<bbtm)
         if bbtm==0
           return RGBA(btop,btop,btop,alpha(ptop))
         else
           pbottom = pbottom*(btop/bbtm)
         endif
       endif
       return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Rev. Pin (Yiq)"
       float btop = 0.299*red(ptop) + 0.587*green(ptop) + 0.114*blue(ptop)
       float bbtm = 0.299*red(pbottom) + 0.587*green(pbottom) \
                    + 0.114*blue(pbottom)
       if (bbtm>=0.5 && btop<bbtm) || (bbtm<0.5 && btop>bbtm)
         if bbtm==0
           return RGBA(btop,btop,btop,alpha(ptop))
         else
           pbottom = pbottom*(btop/bbtm)
         endif
       endif
       return RGBA(red(pbottom),green(pbottom),blue(pbottom),alpha(ptop))
     elseif @p_mmfmergemode=="Soft Quantize"
       int nr = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + red(ptop)) - 1.0))
       int ng = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + green(ptop)) - 1.0))
       int nb = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + blue(ptop)) - 1.0))
       return rgba((1+2*floor(0.9999*nr*red(pbottom)))/(2*nr), \
                   (1+2*floor(0.9999*ng*green(pbottom)))/(2*nb), \
                   (1+2*floor(0.9999*nb*blue(pbottom)))/(2*ng),alpha(ptop))
     elseif @p_mmfmergemode=="Rev. Soft Quantize"
       int nr = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - red(ptop)) - 1.0))
       int ng = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - green(ptop)) - 1.0))
       int nb = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - blue(ptop)) - 1.0))
       return rgba((1+2*floor(0.9999*nr*red(pbottom)))/(2*nr), \
                   (1+2*floor(0.9999*ng*green(pbottom)))/(2*nb), \
                   (1+2*floor(0.9999*nb*blue(pbottom)))/(2*ng),alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Soft Quantize"
       int nr = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + red(pbottom)) - 1.0))
       int ng = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + green(pbottom)) - 1.0))
       int nb = round(@qmax - (@qmax-@qmin)*(2.0/(1.0 + blue(pbottom)) - 1.0))
       return rgba((1+2*floor(0.9999*nr*red(ptop)))/(2*nr), \
                   (1+2*floor(0.9999*ng*green(ptop)))/(2*nb), \
                   (1+2*floor(0.9999*nb*blue(ptop)))/(2*ng),alpha(ptop))
     elseif @p_mmfmergemode=="Inv. Rev. Soft Quantize"
       int nr = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - red(pbottom)) - 1.0))
       int ng = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - green(pbottom)) - 1.0))
       int nb = round(@qmax - (@qmax-@qmin)*(2.0/(2.0 - blue(pbottom)) - 1.0))
       return rgba((1+2*floor(0.9999*nr*red(ptop)))/(2*nr), \
                   (1+2*floor(0.9999*ng*green(ptop)))/(2*nb), \
                   (1+2*floor(0.9999*nb*blue(ptop)))/(2*ng),alpha(ptop))
     elseif @p_mmfmergemode=="Cyan (Inverse Red)"
       return rgba(red(pbottom),green(ptop),blue(ptop),alpha(ptop))
     elseif @p_mmfmergemode=="Magenta (Inverse Green)"
       return rgba(red(ptop),green(pbottom),blue(ptop),alpha(ptop))
     elseif @p_mmfmergemode=="Yellow (Inverse Blue)"
       return rgba(red(ptop),green(ptop),blue(pbottom),alpha(ptop))
     elseif @p_mmfmergemode=="Inverse Hue"
       return hsla(hue(pbottom),sat(ptop),lum(ptop),alpha(ptop))
     elseif @p_mmfmergemode=="Inverse Saturation"
       return hsla(hue(ptop),sat(pbottom),lum(ptop),alpha(ptop))
     elseif @p_mmfmergemode=="Colourize (Inverse Luminance)"
       return hsla(hue(ptop),sat(ptop),lum(pbottom),alpha(ptop))
     elseif @p_mmfmergemode=="Inverse Subtraction"
       float r = red(ptop) - red(pbottom)
       float g = green(ptop) - green(pbottom)
       float b = blue(ptop) - blue(pbottom)
       if r<0.0
         r = 0.0
       endif
       if g<0.0
         g = 0.0
       endif
       if b<0.0
         b = 0.0
       endif
       return rgba(r,g,b,alpha(ptop))
     elseif @p_mmfmergemode=="Double"
       float r = (red(ptop)+1.0)*red(pbottom)
       float g = (green(ptop)+1.0)*green(pbottom)
       float b = (blue(ptop)+1.0)*blue(pbottom)
       if r>1.0
         r = 1.0
       endif
       if g>1.0
         g = 1.0
       endif
       if b>1.0
         b = 1.0
       endif
       return rgba(r,g,b,alpha(ptop))
     else;if @p_mmfmergemode=="Inverse Double"
       float r = (red(pbottom)+1.0)*red(ptop)
       float g = (green(pbottom)+1.0)*green(ptop)
       float b = (blue(pbottom)+1.0)*blue(ptop)
       if r>1.0
         r = 1.0
       endif
       if g>1.0
         g = 1.0
       endif
       if b>1.0
         b = 1.0
       endif
       return rgba(r,g,b,alpha(ptop))
     endif ; @p_mmfmergemode
 
     else;if @pmodeselect=="Original Merge Modes"
 
       return DefaultColorMerge.Merge(pbottom, ptop)
 
     endif ; @p_modeselect
 
   endfunc
 
 default:
   Title = "MMF Extended Colour Merge"
   int param v_mmfextendedcolormerge
     caption = "Version (MMF Extended Colour Merge)"
     enum = "1.0"
     default = 0
     hint = "This field is to absolutely ensure backward compatibility, \
             the default will always be set to the latest version, but \
             there may be some cases where an older effect that you like \
             is lost in an update and you could still use it by selecting \
             the older version number."
     visible = false
   endparam
   int param p_modeselect
     caption = "Merge Modes to choose from"
     enum = "Original Merge Modes" "MMF Merge Modes"
     default = 0
     hint = "Choose from different collections of merge modes."
   endparam
   color func f_mergemode
     caption = "Merge Mode"
     default = mergemultiply()
     hint = "Sets the method used to merge input colors with."
     visible = @p_modeselect=="Original Merge Modes"
   endfunc
   bool param clamp
     caption = "Clamp Values"
     default = false
     hint = "When enabled the RGB values in both the top and bottom colours \
             are clamped to the range 0<=v<=1. Should not be necessary most \
             of the time."
     visible = @p_modeselect=="MMF Merge Modes"
   endparam
   int param p_mmfmergemode
     caption = "MMF Merge Mode"
     enum = "Exclusion" "Fade Down" "Fade Up" "Contrast Down" "Contrast Up" \
            "Dodge" "Burn" "Negation" "Reflect" "Freeze" "Rev. Contrast Down" \
            "Rev. Contrast Up" "Fade" "Reverse Fade" "Contrast" \
            "Reverse Contrast" "Quantize" "Reverse Quantize" "Gamma" \
            "Inverse Gamma" "Reverse Gamma" "Rev. Inv. Gamma" "Combined Gamma" \
            "Rev. Comb. Gamma" "Stamp" "Soft Dodge" "Soft Burn" \
            "Inverse Dodge" "Inverse Burn" "Glow" "Heat" "Inv. Fade Down" \
            "Inv. Fade Up" "Inv. Contrast Down" "Inv. Contrast Up" \
            "Inv. Rev. Con. Down" "Inv. Rev. Con. Up" "Inverse Fade" \
            "Inv. Rev. Fade" "Inverse Contrast" "Inv. Rev. Contrast" \
            "Inverse Quantize" "Inv. Rev. Quantize" "Inv. Gamma" \
            "Inv. Inverse Gamma" "Inv. Reverse Gamma" "Inv. Rev. Inv. Gamma" \
            "Inv. Combined Gamma" "Inv. Rev. Comb. Gamma" "Inverse Stamp" \
            "Brightness (Yiq)" "Colour (Inverse Yiq)" "Brightness (Custom)" \
            "Colour (Custom)" "Pin Light" "Reverse Pin Light" "Inv. Pin Light" \
            "Inv. Rev. Pin Light" "Lighten (Yiq)" "Darken (Yiq)" "Pin (Yiq)" \
            "Reverse Pin (Yiq)" "Inv. Pin (Yiq)" "Inv. Rev. Pin (Yiq)" \
            "Soft Quantize" "Rev. Soft Quantize" "Inv. Soft Quantize" \
            "Inv. Rev. Soft Quantize" "Cyan (Inverse Red)" \
            "Magenta (Inverse Green)" "Yellow (Inverse Blue)" "Inverse Hue" \
            "Inverse Saturation" "Colourize (Inverse Luminance)" \
            "Inverse Subtraction" "Double" "Inverse Double"
     default = 0
     hint = "Extra merge modes, just try them out !"
     visible = @p_modeselect=="MMF Merge Modes"
   endparam
   int param qmin
     caption =  "Minimum Quantize"
     default = 2
     min = 2
     hint = "Sets the minimum number of colour levels used after merging."
     visible = @p_modeselect=="MMF Merge Modes" && \
               (@p_mmfmergemode=="Quantize" \
                || @p_mmfmergemode=="Reverse Quantize" \
                || @p_mmfmergemode=="Inverse Quantize" \
                || @p_mmfmergemode=="Inv. Rev. Quantize" \
                || @p_mmfmergemode=="Soft Quantize" \
                || @p_mmfmergemode=="Rev. Soft Quantize" \
                || @p_mmfmergemode=="Inv. Soft Quantize" \
                || @p_mmfmergemode=="Inv. Rev. Soft Quantize")
   endparam
   int param qmax
     caption = "Maximum Quantize"
     default = 32
     min = 2
     hint = "Sets the maximum number of colour levels used after merging. \
             Should be set larger than 'Minimum Quantize' for correct use."
     visible = @p_modeselect=="MMF Merge Modes" && \
               (@p_mmfmergemode=="Quantize" \
                || @p_mmfmergemode=="Reverse Quantize" \
                || @p_mmfmergemode=="Inverse Quantize" \
                || @p_mmfmergemode=="Inv. Rev. Quantize" \
                || @p_mmfmergemode=="Soft Quantize" \
                || @p_mmfmergemode=="Rev. Soft Quantize" \
                || @p_mmfmergemode=="Inv. Soft Quantize" \
                || @p_mmfmergemode=="Inv. Rev. Soft Quantize")
   endparam
   float param mingamma
     caption = "Minimum Gamma"
     default = 1.0
     min = 1.0
     hint = "Sets the minimum gamma to be used, use 1.0 for 'no change'."
     visible = @p_modeselect=="MMF Merge Modes" && \
               (@p_mmfmergemode=="Gamma" || @p_mmfmergemode=="Inverse Gamma" \
               || @p_mmfmergemode=="Reverse Gamma" \
               || @p_mmfmergemode=="Rev. Inv. Gamma" \
               || @p_mmfmergemode=="Combined Gamma" \
               || @p_mmfmergemode=="Rev. Comb. Gamma" \
               || @p_mmfmergemode=="Inv. Gamma" \
               || @p_mmfmergemode=="Inv. Inverse Gamma" \
               || @p_mmfmergemode=="Inv. Reverse Gamma" \
               || @p_mmfmergemode=="Inv. Rev. Inv. Gamma" \
               || @p_mmfmergemode=="Inv. Combined Gamma" \
               || @p_mmfmergemode=="Inv. Rev. Comb. Gamma")
   endparam
   float param maxgamma
     caption = "Maximum Gamma"
     default = 2.0
     min = 1.0
     hint = "Sets the maximum gamma to be used. Should be set larger than \
             'Minimum Gamma' for correct use."
     visible = @p_modeselect=="MMF Merge Modes" && \
               (@p_mmfmergemode=="Gamma" || @p_mmfmergemode=="Inverse Gamma" \
               || @p_mmfmergemode=="Reverse Gamma" \
               || @p_mmfmergemode=="Rev. Inv. Gamma" \
               || @p_mmfmergemode=="Combined Gamma" \
               || @p_mmfmergemode=="Rev. Comb. Gamma" \
               || @p_mmfmergemode=="Inv. Gamma" \
               || @p_mmfmergemode=="Inv. Inverse Gamma" \
               || @p_mmfmergemode=="Inv. Reverse Gamma" \
               || @p_mmfmergemode=="Inv. Rev. Inv. Gamma" \
               || @p_mmfmergemode=="Inv. Combined Gamma" \
               || @p_mmfmergemode=="Inv. Rev. Comb. Gamma")
   endparam
   float param redlvl
     caption = "Red Factor"
     default = 0.299
     min = 0.0
     hint = "The default value is directly from the red Y value from the YIQ \
             model. The value (relative to the green and blue values) should \
             be based on the relative perception of the brightness of the red \
             monitor colour as compared to the green and blue. The brighter \
             you perceive a colour the larger the value you should use \
             (relatively speaking) but experimenting with wildly different \
             values can produce useful effects."
     visible = @p_modeselect=="MMF Merge Modes" && \
               (@p_mmfmergemode=="Brightness (Custom)" \
                || @p_mmfmergemode=="Colour (Custom)")
   endparam
   float param greenlvl
     caption = "Green Factor"
     default = 0.587
     min = 0.0
     hint = "The default value is directly from the green Y value from the YIQ \
             model. The value (relative to the red and blue values) should \
             be based on the relative perception of the brightness of the green \
             monitor colour as compared to the red and blue. The brighter \
             you perceive a colour the larger the value you should use \
             (relatively speaking) but experimenting with wildly different \
             values can produce useful effects."
     visible = @p_modeselect=="MMF Merge Modes" && \
               (@p_mmfmergemode=="Brightness (Custom)" \
                || @p_mmfmergemode=="Colour (Custom)")
   endparam
   float param bluelvl
     caption = "Blue Factor"
     default = 0.114
     min = 0.0
     hint = "The default value is directly from the blue Y value from the YIQ \
             model. The value (relative to the red and green values) should \
             be based on the relative perception of the brightness of the blue \
             monitor colour as compared to the red and green. The brighter \
             you perceive a colour the larger the value you should use \
             (relatively speaking) but experimenting with wildly different \
             values can produce useful effects."
     visible = @p_modeselect=="MMF Merge Modes" && \
               (@p_mmfmergemode=="Brightness (Custom)" \
                || @p_mmfmergemode=="Colour (Custom)")
   endparam
 }
 


Constructor Summary
MMF_ExtendedColorMerge()
           
MMF_ExtendedColorMerge(Generic pparent)
           
 
Method Summary
 color Merge(color pbottom, color ptop)
          Color merging function
 
Methods inherited from class common:ColorMerge
FullMerge, IsOpaque, Stack
 
Methods inherited from class common:Generic
GetParent
 
Methods inherited from class Object
 

Constructor Detail

MMF_ExtendedColorMerge

public MMF_ExtendedColorMerge(Generic pparent)
Parameters:
pparent - the parent, generally "this" for the parent, or zero

MMF_ExtendedColorMerge

public MMF_ExtendedColorMerge()
Method Detail

Merge

public color Merge(color pbottom,
                   color ptop)
Description copied from class: ColorMerge
Color merging function

Overrides:
Merge in class DefaultColorMerge
Parameters:
pbottom - the base color
ptop - the top color
Returns:
merged color