Advertisement
Guest User

Untitled

a guest
Mar 31st, 2020
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 21.21 KB | None | 0 0
  1. /// <summary>
  2. /// Contains operations to blend colors together.
  3. /// </summary>
  4. public static class Blending
  5. {
  6.     /// <summary>
  7.     /// Describes the blending mode which should be applied
  8.     /// </summary>
  9.     public enum LayerMode :
  10.         ushort
  11.     {
  12.         Normal,
  13.  
  14.         Screen,
  15.         Overlay,
  16.         Dodge,
  17.         Burn,
  18.  
  19.         Add,
  20.         Subtract,
  21.         Multiply,
  22.         Divide,
  23.  
  24.         Min,
  25.         Max,
  26.         Difference,
  27.     }
  28.  
  29.     #region Blending.Apply
  30.  
  31.     public static void Apply(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count, LayerMode mode)
  32.     {
  33.         switch (mode)
  34.         {
  35.             case (LayerMode.Normal): Normal(source, sourceIndex, target, targetIndex, count); break;
  36.  
  37.             case (LayerMode.Screen): Screen(source, sourceIndex, target, targetIndex, count); break;
  38.             case (LayerMode.Overlay): Overlay(source, sourceIndex, target, targetIndex, count); break;
  39.             case (LayerMode.Dodge): Dodge(source, sourceIndex, target, targetIndex, count); break;
  40.             case (LayerMode.Burn): Burn(source, sourceIndex, target, targetIndex, count); break;
  41.  
  42.             case (LayerMode.Add): Add(source, sourceIndex, target, targetIndex, count); break;
  43.             case (LayerMode.Subtract): Subtract(source, sourceIndex, target, targetIndex, count); break;
  44.             case (LayerMode.Multiply): Multiply(source, sourceIndex, target, targetIndex, count); break;
  45.             case (LayerMode.Divide): Divide(source, sourceIndex, target, targetIndex, count); break;
  46.  
  47.             case (LayerMode.Min): Min(source, sourceIndex, target, targetIndex, count); break;
  48.             case (LayerMode.Max): Max(source, sourceIndex, target, targetIndex, count); break;
  49.             case (LayerMode.Difference): Difference(source, sourceIndex, target, targetIndex, count); break;
  50.         }
  51.     }
  52.  
  53.     public static void Apply(c32[] values, int index, int count, c32 other, LayerMode mode)
  54.     {
  55.         switch (mode)
  56.         {
  57.             case (LayerMode.Normal): Normal(values, index, count, other); break;
  58.  
  59.             case (LayerMode.Screen): Screen(values, index, count, other); break;
  60.             case (LayerMode.Overlay): Overlay(values, index, count, other); break;
  61.             case (LayerMode.Dodge): Dodge(values, index, count, other); break;
  62.             case (LayerMode.Burn): Burn(values, index, count, other); break;
  63.  
  64.             case (LayerMode.Add): Add(values, index, count, other); break;
  65.             case (LayerMode.Subtract): Subtract(values, index, count, other); break;
  66.             case (LayerMode.Multiply): Multiply(values, index, count, other); break;
  67.             case (LayerMode.Divide): Divide(values, index, count, other); break;
  68.  
  69.             case (LayerMode.Min): Min(values, index, count, other); break;
  70.             case (LayerMode.Max): Max(values, index, count, other); break;
  71.             case (LayerMode.Difference): Difference(values, index, count, other); break;
  72.         }
  73.     }
  74.  
  75.     public static c32 Apply(c32 value, c32 other, LayerMode mode)
  76.     {
  77.         switch (mode)
  78.         {
  79.             case (LayerMode.Normal): return Normal(value, other);
  80.  
  81.             case (LayerMode.Screen): return Screen(value, other);
  82.             case (LayerMode.Overlay): return Overlay(value, other);
  83.             case (LayerMode.Dodge): return Dodge(value, other);
  84.             case (LayerMode.Burn): return Burn(value, other);
  85.  
  86.             case (LayerMode.Add): return Add(value, other);
  87.             case (LayerMode.Subtract): return Subtract(value, other);
  88.             case (LayerMode.Multiply): return Multiply(value, other);
  89.             case (LayerMode.Divide): return Divide(value, other);
  90.  
  91.             case (LayerMode.Min): return Min(value, other);
  92.             case (LayerMode.Max): return Max(value, other);
  93.             case (LayerMode.Difference): return Difference(value, other);
  94.         }
  95.  
  96.         return value;
  97.     }
  98.  
  99.     #endregion
  100.     #region Blending.Normal
  101.  
  102.     public static void Normal(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count)
  103.     {
  104.         return;
  105.     }
  106.  
  107.     public static void Normal(c32[] values, int index, int count, c32 other)
  108.     {
  109.         return;
  110.     }
  111.  
  112.     public static c32 Normal(c32 value, c32 other)
  113.     {
  114.         return value;
  115.     }
  116.  
  117.     #endregion
  118.    
  119.     #region Blending.Screen
  120.  
  121.     public static void Screen(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count)
  122.     {
  123.         for (int i = 0; i < count; i++)
  124.         {
  125.             c32 value = source[i + sourceIndex];
  126.             c32 other = target[i + targetIndex];
  127.  
  128.             value.R = (byte)(0xFF - (0xFF - value.R) * (0xFF - other.R) / 0xFF);
  129.             value.G = (byte)(0xFF - (0xFF - value.G) * (0xFF - other.G) / 0xFF);
  130.             value.B = (byte)(0xFF - (0xFF - value.B) * (0xFF - other.B) / 0xFF);
  131.             value.A = (byte)(0xFF - (0xFF - value.A) * (0xFF - other.A) / 0xFF);
  132.  
  133.             target[i + targetIndex] = value;
  134.         }
  135.     }
  136.  
  137.     public static void Screen(c32[] values, int index, int count, c32 other)
  138.     {
  139.         for (int i = 0; i < count; i++)
  140.         {
  141.             c32 value = values[i + index];
  142.  
  143.             value.R = (byte)(0xFF - (0xFF - value.R) * (0xFF - other.R) / 0xFF);
  144.             value.G = (byte)(0xFF - (0xFF - value.G) * (0xFF - other.G) / 0xFF);
  145.             value.B = (byte)(0xFF - (0xFF - value.B) * (0xFF - other.B) / 0xFF);
  146.             value.A = (byte)(0xFF - (0xFF - value.A) * (0xFF - other.A) / 0xFF);
  147.  
  148.             values[i + index] = value;
  149.         }
  150.     }
  151.  
  152.     public static c32 Screen(c32 value, c32 other)
  153.     {
  154.         value.R = (byte)(0xFF - (0xFF - value.R) * (0xFF - other.R) / 0xFF);
  155.         value.G = (byte)(0xFF - (0xFF - value.G) * (0xFF - other.G) / 0xFF);
  156.         value.B = (byte)(0xFF - (0xFF - value.B) * (0xFF - other.B) / 0xFF);
  157.         value.A = (byte)(0xFF - (0xFF - value.A) * (0xFF - other.A) / 0xFF);
  158.  
  159.         return value;
  160.     }
  161.  
  162.     #endregion
  163.     #region Blending.Overlay
  164.  
  165.     public static void Overlay(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count)
  166.     {
  167.         for (int i = 0; i < count; i++)
  168.         {
  169.             c32 value = source[i + sourceIndex];
  170.             c32 other = target[i + targetIndex];
  171.  
  172.             if (value.R < 0x80)
  173.                 value.R = (byte)(value.R * other.R / 0x80);
  174.             else
  175.                 value.R = (byte)(0xFF - (0xFF - value.R) * (0xFF - other.R) / 0x80);
  176.  
  177.             if (value.G < 0x80)
  178.                 value.G = (byte)(value.G * other.G / 0x80);
  179.             else
  180.                 value.G = (byte)(0xFF - (0xFF - value.G) * (0xFF - other.G) / 0x80);
  181.  
  182.             if (value.B < 0x80)
  183.                 value.B = (byte)(value.B * other.B / 0x80);
  184.             else
  185.                 value.B = (byte)(0xFF - (0xFF - value.B) * (0xFF - other.B) / 0x80);
  186.  
  187.             if (value.A < 0x80)
  188.                 value.A = (byte)(value.A * other.A / 0x80);
  189.             else
  190.                 value.A = (byte)(0xFF - (0xFF - value.A) * (0xFF - other.A) / 0x80);
  191.  
  192.             target[i + targetIndex] = value;
  193.         }
  194.     }
  195.  
  196.     public static void Overlay(c32[] values, int index, int count, c32 other)
  197.     {
  198.         for (int i = 0; i < count; i++)
  199.         {
  200.             c32 value = values[i + index];
  201.  
  202.             if (value.R < 0x80)
  203.                 value.R = (byte)(value.R * other.R / 0x80);
  204.             else
  205.                 value.R = (byte)(0xFF - (0xFF - value.R) * (0xFF - other.R) / 0x80);
  206.  
  207.             if (value.G < 0x80)
  208.                 value.G = (byte)(value.G * other.G / 0x80);
  209.             else
  210.                 value.G = (byte)(0xFF - (0xFF - value.G) * (0xFF - other.G) / 0x80);
  211.  
  212.             if (value.B < 0x80)
  213.                 value.B = (byte)(value.B * other.B / 0x80);
  214.             else
  215.                 value.B = (byte)(0xFF - (0xFF - value.B) * (0xFF - other.B) / 0x80);
  216.  
  217.             if (value.A < 0x80)
  218.                 value.A = (byte)(value.A * other.A / 0x80);
  219.             else
  220.                 value.A = (byte)(0xFF - (0xFF - value.A) * (0xFF - other.A) / 0x80);
  221.  
  222.             values[i + index] = value;
  223.         }
  224.     }
  225.  
  226.     public static c32 Overlay(c32 value, c32 other)
  227.     {
  228.         if (value.R < 0x80)
  229.             value.R = (byte)(value.R * other.R / 0x80);
  230.         else
  231.             value.R = (byte)(0xFF - (0xFF - value.R) * (0xFF - other.R) / 0x80);
  232.  
  233.         if (value.G < 0x80)
  234.             value.G = (byte)(value.G * other.G / 0x80);
  235.         else
  236.             value.G = (byte)(0xFF - (0xFF - value.G) * (0xFF - other.G) / 0x80);
  237.  
  238.         if (value.B < 0x80)
  239.             value.B = (byte)(value.B * other.B / 0x80);
  240.         else
  241.             value.B = (byte)(0xFF - (0xFF - value.B) * (0xFF - other.B) / 0x80);
  242.  
  243.         if (value.A < 0x80)
  244.             value.A = (byte)(value.A * other.A / 0x80);
  245.         else
  246.             value.A = (byte)(0xFF - (0xFF - value.A) * (0xFF - other.A) / 0x80);
  247.  
  248.         return value;
  249.     }
  250.  
  251.     #endregion
  252.     #region Blending.Dodge
  253.  
  254.     public static void Dodge(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count)
  255.     {
  256.         for (int i = 0; i < count; i++)
  257.         {
  258.             c32 value = source[i + sourceIndex];
  259.             c32 other = target[i + targetIndex];
  260.  
  261.             if (other.R == 0xFF) value.R = 0xFF; else value.R = (byte)Math.Min(0xFF, (0xFF * value.R / (0xFF - other.R)));
  262.             if (other.G == 0xFF) value.G = 0xFF; else value.G = (byte)Math.Min(0xFF, (0xFF * value.G / (0xFF - other.G)));
  263.             if (other.B == 0xFF) value.B = 0xFF; else value.B = (byte)Math.Min(0xFF, (0xFF * value.B / (0xFF - other.B)));
  264.             if (other.A == 0xFF) value.A = 0xFF; else value.A = (byte)Math.Min(0xFF, (0xFF * value.A / (0xFF - other.A)));
  265.  
  266.             target[i + targetIndex] = value;
  267.         }
  268.     }
  269.  
  270.     public static void Dodge(c32[] values, int index, int count, c32 other)
  271.     {
  272.         for (int i = 0; i < count; i++)
  273.         {
  274.             c32 value = values[i + index];
  275.  
  276.             if (other.R == 0xFF) value.R = 0xFF; else value.R = (byte)Math.Min(0xFF, (0xFF * value.R / (0xFF - other.R)));
  277.             if (other.G == 0xFF) value.G = 0xFF; else value.G = (byte)Math.Min(0xFF, (0xFF * value.G / (0xFF - other.G)));
  278.             if (other.B == 0xFF) value.B = 0xFF; else value.B = (byte)Math.Min(0xFF, (0xFF * value.B / (0xFF - other.B)));
  279.             if (other.A == 0xFF) value.A = 0xFF; else value.A = (byte)Math.Min(0xFF, (0xFF * value.A / (0xFF - other.A)));
  280.  
  281.             values[i + index] = value;
  282.         }
  283.     }
  284.  
  285.     public static c32 Dodge(c32 value, c32 other)
  286.     {
  287.         if (other.R == 0xFF) value.R = 0xFF; else value.R = (byte)Math.Min(0xFF, (0xFF * value.R / (0xFF - other.R)));
  288.         if (other.G == 0xFF) value.G = 0xFF; else value.G = (byte)Math.Min(0xFF, (0xFF * value.G / (0xFF - other.G)));
  289.         if (other.B == 0xFF) value.B = 0xFF; else value.B = (byte)Math.Min(0xFF, (0xFF * value.B / (0xFF - other.B)));
  290.         if (other.A == 0xFF) value.A = 0xFF; else value.A = (byte)Math.Min(0xFF, (0xFF * value.A / (0xFF - other.A)));
  291.  
  292.         return value;
  293.     }
  294.  
  295.     #endregion
  296.     #region Blending.Burn
  297.  
  298.     public static void Burn(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count)
  299.     {
  300.         for (int i = 0; i < count; i++)
  301.         {
  302.             c32 value = source[i + sourceIndex];
  303.             c32 other = target[i + targetIndex];
  304.  
  305.             if (other.R == 0x00) value.R = 0x00; else value.R = (byte)Math.Max(0x00, (0xFF - (0xFF - value.R) * 0xFF / other.R));
  306.             if (other.G == 0x00) value.G = 0x00; else value.G = (byte)Math.Max(0x00, (0xFF - (0xFF - value.G) * 0xFF / other.G));
  307.             if (other.B == 0x00) value.B = 0x00; else value.B = (byte)Math.Max(0x00, (0xFF - (0xFF - value.B) * 0xFF / other.B));
  308.             if (other.A == 0x00) value.A = 0x00; else value.A = (byte)Math.Max(0x00, (0xFF - (0xFF - value.A) * 0xFF / other.A));
  309.  
  310.             target[i + targetIndex] = value;
  311.         }
  312.     }
  313.  
  314.     public static void Burn(c32[] values, int index, int count, c32 other)
  315.     {
  316.         for (int i = 0; i < count; i++)
  317.         {
  318.             c32 value = values[i + index];
  319.  
  320.             if (other.R == 0x00) value.R = 0x00; else value.R = (byte)Math.Max(0x00, (0xFF - (0xFF - value.R) * 0xFF / other.R));
  321.             if (other.G == 0x00) value.G = 0x00; else value.G = (byte)Math.Max(0x00, (0xFF - (0xFF - value.G) * 0xFF / other.G));
  322.             if (other.B == 0x00) value.B = 0x00; else value.B = (byte)Math.Max(0x00, (0xFF - (0xFF - value.B) * 0xFF / other.B));
  323.             if (other.A == 0x00) value.A = 0x00; else value.A = (byte)Math.Max(0x00, (0xFF - (0xFF - value.A) * 0xFF / other.A));
  324.  
  325.             values[i + index] = value;
  326.         }
  327.     }
  328.  
  329.     public static c32 Burn(c32 value, c32 other)
  330.     {
  331.         if (other.R == 0x00) value.R = 0x00; else value.R = (byte)Math.Max(0x00, (0xFF - (0xFF - value.R) * 0xFF / other.R));
  332.         if (other.G == 0x00) value.G = 0x00; else value.G = (byte)Math.Max(0x00, (0xFF - (0xFF - value.G) * 0xFF / other.G));
  333.         if (other.B == 0x00) value.B = 0x00; else value.B = (byte)Math.Max(0x00, (0xFF - (0xFF - value.B) * 0xFF / other.B));
  334.         if (other.A == 0x00) value.A = 0x00; else value.A = (byte)Math.Max(0x00, (0xFF - (0xFF - value.A) * 0xFF / other.A));
  335.  
  336.         return value;
  337.     }
  338.  
  339.     #endregion
  340.  
  341.     #region Blending.Add
  342.  
  343.     public static void Add(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count)
  344.     {
  345.         for (int i = 0; i < count; i++)
  346.         {
  347.             c32 value = source[i + sourceIndex];
  348.             c32 other = target[i + targetIndex];
  349.  
  350.             if (value.R + other.R < 0xFF) value.R += other.R; else value.R = 0xFF;
  351.             if (value.G + other.G < 0xFF) value.G += other.G; else value.G = 0xFF;
  352.             if (value.B + other.B < 0xFF) value.B += other.B; else value.B = 0xFF;
  353.             if (value.A + other.A < 0xFF) value.A += other.A; else value.A = 0xFF;
  354.  
  355.             target[i + targetIndex] = value;
  356.         }
  357.     }
  358.  
  359.     public static void Add(c32[] values, int index, int count, c32 other)
  360.     {
  361.         for (int i = 0; i < count; i++)
  362.         {
  363.             c32 value = values[i + index];
  364.  
  365.             if (value.R + other.R < 0xFF) value.R += other.R; else value.R = 0xFF;
  366.             if (value.G + other.G < 0xFF) value.G += other.G; else value.G = 0xFF;
  367.             if (value.B + other.B < 0xFF) value.B += other.B; else value.B = 0xFF;
  368.             if (value.A + other.A < 0xFF) value.A += other.A; else value.A = 0xFF;
  369.  
  370.             values[i + index] = value;
  371.         }
  372.     }
  373.  
  374.     public static c32 Add(c32 value, c32 other)
  375.     {
  376.         if (value.R + other.R < 0xFF) value.R += other.R; else value.R = 0xFF;
  377.         if (value.G + other.G < 0xFF) value.G += other.G; else value.G = 0xFF;
  378.         if (value.B + other.B < 0xFF) value.B += other.B; else value.B = 0xFF;
  379.         if (value.A + other.A < 0xFF) value.A += other.A; else value.A = 0xFF;
  380.  
  381.         return value;
  382.     }
  383.  
  384.     #endregion
  385.     #region Blending.Subtract
  386.  
  387.     public static void Subtract(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count)
  388.     {
  389.         for (int i = 0; i < count; i++)
  390.         {
  391.             c32 value = source[i + sourceIndex];
  392.             c32 other = target[i + targetIndex];
  393.  
  394.             if (value.R > other.R) value.R -= other.R; else value.R = 0x00;
  395.             if (value.G > other.G) value.G -= other.G; else value.G = 0x00;
  396.             if (value.B > other.B) value.B -= other.B; else value.B = 0x00;
  397.             if (value.A > other.A) value.A -= other.R; else value.A = 0x00;
  398.  
  399.             target[i + targetIndex] = value;
  400.         }
  401.     }
  402.  
  403.     public static void Subtract(c32[] values, int index, int count, c32 other)
  404.     {
  405.         for (int i = 0; i < count; i++)
  406.         {
  407.             c32 value = values[i + index];
  408.  
  409.             if (value.R > other.R) value.R -= other.R; else value.R = 0x00;
  410.             if (value.G > other.G) value.G -= other.G; else value.G = 0x00;
  411.             if (value.B > other.B) value.B -= other.B; else value.B = 0x00;
  412.             if (value.A > other.A) value.A -= other.R; else value.A = 0x00;
  413.  
  414.             values[i + index] = value;
  415.         }
  416.     }
  417.  
  418.     public static c32 Subtract(c32 value, c32 other)
  419.     {
  420.         if (value.R > other.R) value.R -= other.R; else value.R = 0x00;
  421.         if (value.G > other.G) value.G -= other.G; else value.G = 0x00;
  422.         if (value.B > other.B) value.B -= other.B; else value.B = 0x00;
  423.         if (value.A > other.A) value.A -= other.R; else value.A = 0x00;
  424.  
  425.         return value;
  426.     }
  427.  
  428.     #endregion
  429.     #region Blending.Multiply
  430.  
  431.     public static void Multiply(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count)
  432.     {
  433.         for (int i = 0; i < count; i++)
  434.         {
  435.             c32 value = source[i + sourceIndex];
  436.             c32 other = target[i + targetIndex];
  437.  
  438.             value.R = (byte)(value.R * other.R / 0xFF);
  439.             value.G = (byte)(value.G * other.G / 0xFF);
  440.             value.B = (byte)(value.B * other.B / 0xFF);
  441.             value.A = (byte)(value.A * other.A / 0xFF);
  442.  
  443.             target[i + targetIndex] = value;
  444.         }
  445.     }
  446.  
  447.     public static void Multiply(c32[] values, int index, int count, c32 other)
  448.     {
  449.         for (int i = 0; i < count; i++)
  450.         {
  451.             c32 value = values[i + index];
  452.  
  453.             value.R = (byte)(value.R * other.R / 0xFF);
  454.             value.G = (byte)(value.G * other.G / 0xFF);
  455.             value.B = (byte)(value.B * other.B / 0xFF);
  456.             value.A = (byte)(value.A * other.A / 0xFF);
  457.  
  458.             values[i + index] = value;
  459.         }
  460.     }
  461.  
  462.     public static c32 Multiply(c32 value, c32 other)
  463.     {
  464.         value.R = (byte)(value.R * other.R / 0xFF);
  465.         value.G = (byte)(value.G * other.G / 0xFF);
  466.         value.B = (byte)(value.B * other.B / 0xFF);
  467.         value.A = (byte)(value.A * other.A / 0xFF);
  468.  
  469.         return value;
  470.     }
  471.  
  472.     #endregion
  473.     #region Blending.Divide
  474.  
  475.     public static void Divide(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count)
  476.     {
  477.         for (int i = 0; i < count; i++)
  478.         {
  479.             c32 value = source[i + sourceIndex];
  480.             c32 other = target[i + targetIndex];
  481.  
  482.             if (other.R == 0x00) value.R = 0xFF; else value.R = (byte)Math.Min(0xFF, (value.R * 0xFF / other.R));
  483.             if (other.R == 0x00) value.G = 0xFF; else value.G = (byte)Math.Min(0xFF, (value.G * 0xFF / other.G));
  484.             if (other.R == 0x00) value.B = 0xFF; else value.B = (byte)Math.Min(0xFF, (value.B * 0xFF / other.B));
  485.             if (other.R == 0x00) value.A = 0xFF; else value.A = (byte)Math.Min(0xFF, (value.A * 0xFF / other.A));
  486.  
  487.             target[i + targetIndex] = value;
  488.         }
  489.     }
  490.  
  491.     public static void Divide(c32[] values, int index, int count, c32 other)
  492.     {
  493.         for (int i = 0; i < count; i++)
  494.         {
  495.             c32 value = values[i + index];
  496.  
  497.             if (other.R == 0x00) value.R = 0xFF; else value.R = (byte)Math.Min(0xFF, (value.R * 0xFF / other.R));
  498.             if (other.R == 0x00) value.G = 0xFF; else value.G = (byte)Math.Min(0xFF, (value.G * 0xFF / other.G));
  499.             if (other.R == 0x00) value.B = 0xFF; else value.B = (byte)Math.Min(0xFF, (value.B * 0xFF / other.B));
  500.             if (other.R == 0x00) value.A = 0xFF; else value.A = (byte)Math.Min(0xFF, (value.A * 0xFF / other.A));
  501.  
  502.             values[i + index] = value;
  503.         }
  504.     }
  505.  
  506.     public static c32 Divide(c32 value, c32 other)
  507.     {
  508.         if (other.R == 0x00) value.R = 0xFF; else value.R = (byte)Math.Min(0xFF, (value.R * 0xFF / other.R));
  509.         if (other.R == 0x00) value.G = 0xFF; else value.G = (byte)Math.Min(0xFF, (value.G * 0xFF / other.G));
  510.         if (other.R == 0x00) value.B = 0xFF; else value.B = (byte)Math.Min(0xFF, (value.B * 0xFF / other.B));
  511.         if (other.R == 0x00) value.A = 0xFF; else value.A = (byte)Math.Min(0xFF, (value.A * 0xFF / other.A));
  512.  
  513.         return value;
  514.     }
  515.  
  516.     #endregion
  517.  
  518.     #region Blending.Min
  519.  
  520.     public static void Min(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count)
  521.     {
  522.         for (int i = 0; i < count; i++)
  523.         {
  524.             c32 value = source[i + sourceIndex];
  525.             c32 other = target[i + targetIndex];
  526.  
  527.             if (value.R > other.R) value.R = other.R;
  528.             if (value.G > other.G) value.G = other.G;
  529.             if (value.B > other.B) value.B = other.B;
  530.             if (value.A > other.A) value.A = other.A;
  531.  
  532.             target[i + targetIndex] = value;
  533.         }
  534.     }
  535.  
  536.     public static void Min(c32[] values, int index, int count, c32 other)
  537.     {
  538.         for (int i = 0; i < count; i++)
  539.         {
  540.             c32 value = values[i + index];
  541.  
  542.             if (value.R > other.R) value.R = other.R;
  543.             if (value.G > other.G) value.G = other.G;
  544.             if (value.B > other.B) value.B = other.B;
  545.             if (value.A > other.A) value.A = other.A;
  546.  
  547.             values[i + index] = value;
  548.         }
  549.     }
  550.  
  551.     public static c32 Min(c32 value, c32 other)
  552.     {
  553.         if (value.R > other.R) value.R = other.R;
  554.         if (value.G > other.G) value.G = other.G;
  555.         if (value.B > other.B) value.B = other.B;
  556.         if (value.A > other.A) value.A = other.A;
  557.  
  558.         return value;
  559.     }
  560.  
  561.     #endregion
  562.     #region Blending.Max
  563.  
  564.     public static void Max(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count)
  565.     {
  566.         for (int i = 0; i < count; i++)
  567.         {
  568.             c32 value = source[i + sourceIndex];
  569.             c32 other = target[i + targetIndex];
  570.  
  571.             if (value.R < other.R) value.R = other.R;
  572.             if (value.G < other.G) value.G = other.G;
  573.             if (value.B < other.B) value.B = other.B;
  574.             if (value.A < other.A) value.A = other.A;
  575.  
  576.             target[i + targetIndex] = value;
  577.         }
  578.     }
  579.  
  580.     public static void Max(c32[] values, int index, int count, c32 other)
  581.     {
  582.         for (int i = 0; i < count; i++)
  583.         {
  584.             c32 value = values[i + index];
  585.  
  586.             if (value.R < other.R) value.R = other.R;
  587.             if (value.G < other.G) value.G = other.G;
  588.             if (value.B < other.B) value.B = other.B;
  589.             if (value.A < other.A) value.A = other.A;
  590.  
  591.             values[i + index] = value;
  592.         }
  593.     }
  594.  
  595.     public static c32 Max(c32 value, c32 other)
  596.     {
  597.         if (value.R < other.R) value.R = other.R;
  598.         if (value.G < other.G) value.G = other.G;
  599.         if (value.B < other.B) value.B = other.B;
  600.         if (value.A < other.A) value.A = other.A;
  601.  
  602.         return value;
  603.     }
  604.  
  605.     #endregion
  606.     #region Blending.Difference
  607.  
  608.     public static void Difference(c32[] source, int sourceIndex, c32[] target, int targetIndex, int count)
  609.     {
  610.         for (int i = 0; i < count; i++)
  611.         {
  612.             c32 value = source[i + sourceIndex];
  613.             c32 other = target[i + targetIndex];
  614.  
  615.             if (value.R > other.R) value.R -= other.R; else value.R = (byte)(other.R - value.R);
  616.             if (value.G > other.G) value.G -= other.G; else value.G = (byte)(other.G - value.G);
  617.             if (value.B > other.B) value.B -= other.B; else value.B = (byte)(other.B - value.B);
  618.             if (value.A > other.A) value.A -= other.A; else value.A = (byte)(other.A - value.A);
  619.  
  620.             target[i + targetIndex] = value;
  621.         }
  622.     }
  623.  
  624.     public static void Difference(c32[] values, int index, int count, c32 other)
  625.     {
  626.         for (int i = 0; i < count; i++)
  627.         {
  628.             c32 value = values[i + index];
  629.  
  630.             if (value.R > other.R) value.R -= other.R; else value.R = (byte)(other.R - value.R);
  631.             if (value.G > other.G) value.G -= other.G; else value.G = (byte)(other.G - value.G);
  632.             if (value.B > other.B) value.B -= other.B; else value.B = (byte)(other.B - value.B);
  633.             if (value.A > other.A) value.A -= other.A; else value.A = (byte)(other.A - value.A);
  634.  
  635.             values[i + index] = value;
  636.         }
  637.     }
  638.  
  639.     public static c32 Difference(c32 value, c32 other)
  640.     {
  641.         if (value.R > other.R) value.R -= other.R; else value.R = (byte)(other.R - value.R);
  642.         if (value.G > other.G) value.G -= other.G; else value.G = (byte)(other.G - value.G);
  643.         if (value.B > other.B) value.B -= other.B; else value.B = (byte)(other.B - value.B);
  644.         if (value.A > other.A) value.A -= other.A; else value.A = (byte)(other.A - value.A);
  645.  
  646.         return value;
  647.     }
  648.  
  649.     #endregion
  650. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement