13dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta/* 23dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * Copyright (C) 2014 The Android Open Source Project 33dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * 43dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * Licensed under the Apache License, Version 2.0 (the "License"); 53dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * you may not use this file except in compliance with the License. 63dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * You may obtain a copy of the License at 73dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * 83dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * http://www.apache.org/licenses/LICENSE-2.0 93dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * 103dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * Unless required by applicable law or agreed to in writing, software 113dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * distributed under the License is distributed on an "AS IS" BASIS, 123dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * See the License for the specific language governing permissions and 143dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * limitations under the License. 153dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta */ 163dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 173dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Guptapackage android.graphics; 183dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 193dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Guptaimport java.awt.Composite; 203dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Guptaimport java.awt.CompositeContext; 213dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Guptaimport java.awt.RenderingHints; 223dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Guptaimport java.awt.image.ColorModel; 233dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Guptaimport java.awt.image.DataBuffer; 243dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Guptaimport java.awt.image.Raster; 253dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Guptaimport java.awt.image.WritableRaster; 263dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 273dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta/* 283dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * (non-Javadoc) 293dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * The class is adapted from a demo tool for Blending Modes written by 303dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * Romain Guy (romainguy@android.com). The tool is available at 313dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta * http://www.curious-creature.org/2006/09/20/new-blendings-modes-for-java2d/ 323dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta */ 333dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Guptapublic final class BlendComposite implements Composite { 343dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public enum BlendingMode { 353dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta NORMAL, 363dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta AVERAGE, 373dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta MULTIPLY, 383dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta SCREEN, 393dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta DARKEN, 403dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta LIGHTEN, 413dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta OVERLAY, 423dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta HARD_LIGHT, 433dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta SOFT_LIGHT, 443dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta DIFFERENCE, 453dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta NEGATION, 463dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta EXCLUSION, 473dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta COLOR_DODGE, 483dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta INVERSE_COLOR_DODGE, 493dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta SOFT_DODGE, 503dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta COLOR_BURN, 513dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta INVERSE_COLOR_BURN, 523dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta SOFT_BURN, 533dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta REFLECT, 543dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta GLOW, 553dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta FREEZE, 563dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta HEAT, 573dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta ADD, 583dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta SUBTRACT, 593dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta STAMP, 603dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta RED, 613dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta GREEN, 623dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta BLUE, 633dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta HUE, 643dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta SATURATION, 653dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta COLOR, 663dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta LUMINOSITY 673dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 683dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 693dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Normal = new BlendComposite(BlendingMode.NORMAL); 703dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Average = new BlendComposite(BlendingMode.AVERAGE); 713dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Multiply = new BlendComposite(BlendingMode.MULTIPLY); 723dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Screen = new BlendComposite(BlendingMode.SCREEN); 733dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Darken = new BlendComposite(BlendingMode.DARKEN); 743dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Lighten = new BlendComposite(BlendingMode.LIGHTEN); 753dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Overlay = new BlendComposite(BlendingMode.OVERLAY); 763dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite HardLight = new BlendComposite(BlendingMode.HARD_LIGHT); 773dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite SoftLight = new BlendComposite(BlendingMode.SOFT_LIGHT); 783dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Difference = new BlendComposite(BlendingMode.DIFFERENCE); 793dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Negation = new BlendComposite(BlendingMode.NEGATION); 803dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Exclusion = new BlendComposite(BlendingMode.EXCLUSION); 813dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite ColorDodge = new BlendComposite(BlendingMode.COLOR_DODGE); 823dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite InverseColorDodge = new BlendComposite(BlendingMode.INVERSE_COLOR_DODGE); 833dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite SoftDodge = new BlendComposite(BlendingMode.SOFT_DODGE); 843dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite ColorBurn = new BlendComposite(BlendingMode.COLOR_BURN); 853dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite InverseColorBurn = new BlendComposite(BlendingMode.INVERSE_COLOR_BURN); 863dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite SoftBurn = new BlendComposite(BlendingMode.SOFT_BURN); 873dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Reflect = new BlendComposite(BlendingMode.REFLECT); 883dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Glow = new BlendComposite(BlendingMode.GLOW); 893dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Freeze = new BlendComposite(BlendingMode.FREEZE); 903dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Heat = new BlendComposite(BlendingMode.HEAT); 913dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Add = new BlendComposite(BlendingMode.ADD); 923dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Subtract = new BlendComposite(BlendingMode.SUBTRACT); 933dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Stamp = new BlendComposite(BlendingMode.STAMP); 943dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Red = new BlendComposite(BlendingMode.RED); 953dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Green = new BlendComposite(BlendingMode.GREEN); 963dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Blue = new BlendComposite(BlendingMode.BLUE); 973dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Hue = new BlendComposite(BlendingMode.HUE); 983dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Saturation = new BlendComposite(BlendingMode.SATURATION); 993dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Color = new BlendComposite(BlendingMode.COLOR); 1003dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static final BlendComposite Luminosity = new BlendComposite(BlendingMode.LUMINOSITY); 1013dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1023dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private float alpha; 1033dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private BlendingMode mode; 1043dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1053dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private BlendComposite(BlendingMode mode) { 1063dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta this(mode, 1.0f); 1073dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1083dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1093dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private BlendComposite(BlendingMode mode, float alpha) { 1103dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta this.mode = mode; 1113dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta setAlpha(alpha); 1123dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1133dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1143dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static BlendComposite getInstance(BlendingMode mode) { 1153dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new BlendComposite(mode); 1163dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1173dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1183dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static BlendComposite getInstance(BlendingMode mode, float alpha) { 1193dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new BlendComposite(mode, alpha); 1203dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1213dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1223dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public BlendComposite derive(BlendingMode mode) { 1233dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return this.mode == mode ? this : new BlendComposite(mode, getAlpha()); 1243dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1253dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1263dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public BlendComposite derive(float alpha) { 1273dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return this.alpha == alpha ? this : new BlendComposite(getMode(), alpha); 1283dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1293dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1303dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public float getAlpha() { 1313dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return alpha; 1323dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1333dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1343dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public BlendingMode getMode() { 1353dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return mode; 1363dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1373dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1383dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private void setAlpha(float alpha) { 1393dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (alpha < 0.0f || alpha > 1.0f) { 1403dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta throw new IllegalArgumentException( 1413dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta "alpha must be comprised between 0.0f and 1.0f"); 1423dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1433dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1443dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta this.alpha = alpha; 1453dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1463dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1473dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 1483dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public int hashCode() { 1493dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return Float.floatToIntBits(alpha) * 31 + mode.ordinal(); 1503dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1513dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1523dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 1533dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public boolean equals(Object obj) { 1543dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (!(obj instanceof BlendComposite)) { 1553dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return false; 1563dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1573dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1583dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta BlendComposite bc = (BlendComposite) obj; 1593dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1603dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (mode != bc.mode) { 1613dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return false; 1623dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1633dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1643dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return alpha == bc.alpha; 1653dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1663dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1673dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public CompositeContext createContext(ColorModel srcColorModel, 1683dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta ColorModel dstColorModel, 1693dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta RenderingHints hints) { 1703dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new BlendingContext(this); 1713dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1723dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1733dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private static final class BlendingContext implements CompositeContext { 1743dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private final Blender blender; 1753dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private final BlendComposite composite; 1763dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1773dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private BlendingContext(BlendComposite composite) { 1783dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta this.composite = composite; 1793dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta this.blender = Blender.getBlenderFor(composite); 1803dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1813dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1823dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public void dispose() { 1833dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1843dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1853dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public void compose(Raster src, Raster dstIn, WritableRaster dstOut) { 1863dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (src.getSampleModel().getDataType() != DataBuffer.TYPE_INT || 1873dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dstIn.getSampleModel().getDataType() != DataBuffer.TYPE_INT || 1883dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dstOut.getSampleModel().getDataType() != DataBuffer.TYPE_INT) { 1893dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta throw new IllegalStateException( 1903dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta "Source and destination must store pixels as INT."); 1913dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 1923dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1933dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta int width = Math.min(src.getWidth(), dstIn.getWidth()); 1943dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta int height = Math.min(src.getHeight(), dstIn.getHeight()); 1953dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1963dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float alpha = composite.getAlpha(); 1973dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 1983dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta int[] srcPixel = new int[4]; 1993dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta int[] dstPixel = new int[4]; 20047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta int[] result = new int[4]; 2013dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta int[] srcPixels = new int[width]; 2023dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta int[] dstPixels = new int[width]; 2033dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 2043dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta for (int y = 0; y < height; y++) { 2053dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dstIn.getDataElements(0, y, width, 1, dstPixels); 20647fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta if (alpha != 0) { 20747fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta src.getDataElements(0, y, width, 1, srcPixels); 20847fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int x = 0; x < width; x++) { 20947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta // pixels are stored as INT_ARGB 21047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta // our arrays are [R, G, B, A] 21147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta int pixel = srcPixels[x]; 21247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta srcPixel[0] = (pixel >> 16) & 0xFF; 21347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta srcPixel[1] = (pixel >> 8) & 0xFF; 21447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta srcPixel[2] = (pixel ) & 0xFF; 21547fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta srcPixel[3] = (pixel >> 24) & 0xFF; 21647fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta 21747fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta pixel = dstPixels[x]; 21847fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta dstPixel[0] = (pixel >> 16) & 0xFF; 21947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta dstPixel[1] = (pixel >> 8) & 0xFF; 22047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta dstPixel[2] = (pixel ) & 0xFF; 22147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta dstPixel[3] = (pixel >> 24) & 0xFF; 22247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta 22347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result = blender.blend(srcPixel, dstPixel, result); 22447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta 22547fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta // mixes the result with the opacity 22647fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta if (alpha == 1) { 22747fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta dstPixels[x] = (result[3] & 0xFF) << 24 | 22847fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta (result[0] & 0xFF) << 16 | 22947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta (result[1] & 0xFF) << 8 | 23047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[2] & 0xFF; 23147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } else { 23247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta dstPixels[x] = 23347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta ((int) (dstPixel[3] + (result[3] - dstPixel[3]) * alpha) & 0xFF) << 24 | 23447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta ((int) (dstPixel[0] + (result[0] - dstPixel[0]) * alpha) & 0xFF) << 16 | 23547fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta ((int) (dstPixel[1] + (result[1] - dstPixel[1]) * alpha) & 0xFF) << 8 | 2363dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta (int) (dstPixel[2] + (result[2] - dstPixel[2]) * alpha) & 0xFF; 23747fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 23847fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta 23947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 24047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 2413dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dstOut.setDataElements(0, y, width, 1, dstPixels); 2423dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 2433dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 2443dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 2453dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 2463dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private static abstract class Blender { 24747fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public abstract int[] blend(int[] src, int[] dst, int[] result); 2483dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 2493dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private static void RGBtoHSL(int r, int g, int b, float[] hsl) { 2503dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float var_R = (r / 255f); 2513dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float var_G = (g / 255f); 2523dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float var_B = (b / 255f); 2533dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 2543dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float var_Min; 2553dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float var_Max; 2563dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float del_Max; 2573dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 2583dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (var_R > var_G) { 2593dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta var_Min = var_G; 2603dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta var_Max = var_R; 2613dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } else { 2623dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta var_Min = var_R; 2633dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta var_Max = var_G; 2643dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 2653dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (var_B > var_Max) { 2663dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta var_Max = var_B; 2673dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 2683dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (var_B < var_Min) { 2693dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta var_Min = var_B; 2703dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 2713dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 2723dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta del_Max = var_Max - var_Min; 2733dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 2743dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float H, S, L; 2753dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta L = (var_Max + var_Min) / 2f; 2763dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 2773dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (del_Max - 0.01f <= 0.0f) { 2783dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta H = 0; 2793dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta S = 0; 2803dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } else { 2813dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (L < 0.5f) { 2823dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta S = del_Max / (var_Max + var_Min); 2833dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } else { 2843dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta S = del_Max / (2 - var_Max - var_Min); 2853dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 2863dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 2873dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float del_R = (((var_Max - var_R) / 6f) + (del_Max / 2f)) / del_Max; 2883dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float del_G = (((var_Max - var_G) / 6f) + (del_Max / 2f)) / del_Max; 2893dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float del_B = (((var_Max - var_B) / 6f) + (del_Max / 2f)) / del_Max; 2903dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 2913dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (var_R == var_Max) { 2923dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta H = del_B - del_G; 2933dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } else if (var_G == var_Max) { 2943dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta H = (1 / 3f) + del_R - del_B; 2953dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } else { 2963dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta H = (2 / 3f) + del_G - del_R; 2973dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 2983dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (H < 0) { 2993dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta H += 1; 3003dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3013dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (H > 1) { 3023dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta H -= 1; 3033dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3043dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3053dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 3063dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta hsl[0] = H; 3073dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta hsl[1] = S; 3083dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta hsl[2] = L; 3093dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3103dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 3113dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private static void HSLtoRGB(float h, float s, float l, int[] rgb) { 3123dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta int R, G, B; 3133dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 3143dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (s - 0.01f <= 0.0f) { 3153dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta R = (int) (l * 255.0f); 3163dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta G = (int) (l * 255.0f); 3173dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta B = (int) (l * 255.0f); 3183dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } else { 3193dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float var_1, var_2; 3203dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (l < 0.5f) { 3213dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta var_2 = l * (1 + s); 3223dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } else { 3233dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta var_2 = (l + s) - (s * l); 3243dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3253dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta var_1 = 2 * l - var_2; 3263dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 3273dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta R = (int) (255.0f * hue2RGB(var_1, var_2, h + (1.0f / 3.0f))); 3283dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta G = (int) (255.0f * hue2RGB(var_1, var_2, h)); 3293dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta B = (int) (255.0f * hue2RGB(var_1, var_2, h - (1.0f / 3.0f))); 3303dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3313dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 3323dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta rgb[0] = R; 3333dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta rgb[1] = G; 3343dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta rgb[2] = B; 3353dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3363dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 3373dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta private static float hue2RGB(float v1, float v2, float vH) { 3383dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (vH < 0.0f) { 3393dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta vH += 1.0f; 3403dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3413dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if (vH > 1.0f) { 3423dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta vH -= 1.0f; 3433dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3443dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if ((6.0f * vH) < 1.0f) { 3453dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return (v1 + (v2 - v1) * 6.0f * vH); 3463dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3473dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if ((2.0f * vH) < 1.0f) { 3483dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return (v2); 3493dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3503dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta if ((3.0f * vH) < 2.0f) { 3513dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return (v1 + (v2 - v1) * ((2.0f / 3.0f) - vH) * 6.0f); 3523dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3533dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return (v1); 3543dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3553dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 3563dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta public static Blender getBlenderFor(BlendComposite composite) { 3573dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta switch (composite.getMode()) { 3583dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case NORMAL: 3593dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 3603dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 36147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 36247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta System.arraycopy(src, 0, result, 0, 4); 36347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 3643dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3653dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 3663dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case ADD: 3673dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 3683dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 36947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 37047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int i = 0; i < 4; i++) { 37147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[i] = Math.min(255, src[i] + dst[i]); 37247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 37347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 3743dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3753dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 3763dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case AVERAGE: 3773dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 3783dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 37947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 38047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int i = 0; i < 3; i++) { 38147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[i] = (src[i] + dst[i]) >> 1; 38247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 38347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 38447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 3853dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3863dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 3873dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case BLUE: 3883dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 3893dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 39047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 39147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta System.arraycopy(dst, 0, result, 0, 3); 39247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 39347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 3943dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 3953dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 3963dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case COLOR: 3973dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 3983dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 39947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 4003dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float[] srcHSL = new float[3]; 4013dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta RGBtoHSL(src[0], src[1], src[2], srcHSL); 4023dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float[] dstHSL = new float[3]; 4033dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta RGBtoHSL(dst[0], dst[1], dst[2], dstHSL); 4043dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 4053dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta HSLtoRGB(srcHSL[0], srcHSL[1], dstHSL[2], result); 4063dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 4073dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 4083dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return result; 4093dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 4103dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 4113dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case COLOR_BURN: 4123dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 4133dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 41447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 41547fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int i = 0; i < 3; i++) { 41647fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[i] = src[i] == 0 ? 0 : 41747fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta Math.max(0, 255 - (((255 - dst[i]) << 8) / src[i])); 41847fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 41947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 42047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 4213dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 4223dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 4233dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case COLOR_DODGE: 4243dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 4253dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 42647fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 42747fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int i = 0; i < 3; i++) { 42847fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[i] = src[i] == 255 ? 255 : 42947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta Math.min((dst[i] << 8) / (255 - src[i]), 255); 43047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 43147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 43247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 4333dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 4343dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 4353dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case DARKEN: 4363dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 4373dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 43847fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 43947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int i = 0; i < 3; i++) { 44047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[i] = Math.min(src[i], dst[i]); 44147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 44247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 44347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 4443dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 4453dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 4463dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case DIFFERENCE: 4473dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 4483dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 44947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 45047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int i = 0; i < 3; i++) { 45147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[i] = dst[i] + src[i] - (dst[i] * src[i] >> 7); 45247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 45347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 45447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 4553dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 4563dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 4573dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case EXCLUSION: 4583dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 4593dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 46047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 46147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int i = 0; i < 3; i++) { 46247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[i] = dst[i] + src[i] - (dst[i] * src[i] >> 7); 46347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 46447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 46547fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 4663dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 4673dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 4683dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case FREEZE: 4693dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 4703dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 47147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 47247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int i = 0; i < 3; i++) { 47347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[i] = src[i] == 0 ? 0 : 47447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta Math.max(0, 255 - (255 - dst[i]) * (255 - dst[i]) / src[i]); 47547fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 47647fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 47747fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 4783dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 4793dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 4803dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case GLOW: 4813dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 4823dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 48347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 48447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int i = 0; i < 3; i++) { 48547fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[i] = dst[i] == 255 ? 255 : 48647fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta Math.min(255, src[i] * src[i] / (255 - dst[i])); 48747fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 48847fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 48947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 4903dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 4913dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 4923dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case GREEN: 4933dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 4943dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 49547fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 4963dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 4973dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[0], 4983dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[1], 4993dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta src[2], 5003dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 5013dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 5023dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 5033dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 5043dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case HARD_LIGHT: 5053dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 5063dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 50747fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 5083dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 5093dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta src[0] < 128 ? dst[0] * src[0] >> 7 : 5103dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 255 - ((255 - src[0]) * (255 - dst[0]) >> 7), 5113dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta src[1] < 128 ? dst[1] * src[1] >> 7 : 5123dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 255 - ((255 - src[1]) * (255 - dst[1]) >> 7), 5133dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta src[2] < 128 ? dst[2] * src[2] >> 7 : 5143dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 255 - ((255 - src[2]) * (255 - dst[2]) >> 7), 5153dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 5163dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 5173dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 5183dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 5193dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case HEAT: 5203dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 5213dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 52247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 5233dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 5243dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[0] == 0 ? 0 : Math.max(0, 255 - (255 - src[0]) * (255 - src[0]) / dst[0]), 5253dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[1] == 0 ? 0 : Math.max(0, 255 - (255 - src[1]) * (255 - src[1]) / dst[1]), 5263dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[2] == 0 ? 0 : Math.max(0, 255 - (255 - src[2]) * (255 - src[2]) / dst[2]), 5273dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 5283dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 5293dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 5303dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 5313dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case HUE: 5323dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 5333dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 53447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 5353dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float[] srcHSL = new float[3]; 5363dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta RGBtoHSL(src[0], src[1], src[2], srcHSL); 5373dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float[] dstHSL = new float[3]; 5383dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta RGBtoHSL(dst[0], dst[1], dst[2], dstHSL); 5393dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 5403dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta HSLtoRGB(srcHSL[0], dstHSL[1], dstHSL[2], result); 5413dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 5423dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 5433dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return result; 5443dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 5453dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 5463dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case INVERSE_COLOR_BURN: 5473dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 5483dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 54947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 5503dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 5513dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[0] == 0 ? 0 : 5523dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, 255 - (((255 - src[0]) << 8) / dst[0])), 5533dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[1] == 0 ? 0 : 5543dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, 255 - (((255 - src[1]) << 8) / dst[1])), 5553dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[2] == 0 ? 0 : 5563dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, 255 - (((255 - src[2]) << 8) / dst[2])), 5573dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 5583dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 5593dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 5603dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 5613dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case INVERSE_COLOR_DODGE: 5623dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 5633dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 56447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 5653dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 5663dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[0] == 255 ? 255 : 5673dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min((src[0] << 8) / (255 - dst[0]), 255), 5683dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[1] == 255 ? 255 : 5693dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min((src[1] << 8) / (255 - dst[1]), 255), 5703dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[2] == 255 ? 255 : 5713dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min((src[2] << 8) / (255 - dst[2]), 255), 5723dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 5733dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 5743dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 5753dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 5763dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case LIGHTEN: 5773dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 5783dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 57947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 58047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int i = 0; i < 3; i++) { 58147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[i] = Math.max(src[i], dst[i]); 58247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 58347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 58447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 5853dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 5863dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 5873dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case LUMINOSITY: 5883dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 5893dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 59047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 5913dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float[] srcHSL = new float[3]; 5923dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta RGBtoHSL(src[0], src[1], src[2], srcHSL); 5933dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float[] dstHSL = new float[3]; 5943dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta RGBtoHSL(dst[0], dst[1], dst[2], dstHSL); 5953dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 5963dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta HSLtoRGB(dstHSL[0], dstHSL[1], srcHSL[2], result); 5973dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 5983dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 5993dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return result; 6003dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 6013dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 6023dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case MULTIPLY: 6033dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 6043dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 60547fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 60647fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int i = 0; i < 3; i++) { 60747fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[i] = (src[i] * dst[i]) >> 8; 60847fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 60947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 61047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 6113dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 6123dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 6133dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case NEGATION: 6143dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 6153dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 61647fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 6173dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 6183dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 255 - Math.abs(255 - dst[0] - src[0]), 6193dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 255 - Math.abs(255 - dst[1] - src[1]), 6203dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 255 - Math.abs(255 - dst[2] - src[2]), 6213dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 6223dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 6233dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 6243dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 6253dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case OVERLAY: 6263dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 6273dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 62847fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 62947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta for (int i = 0; i < 3; i++) { 63047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[i] = dst[i] < 128 ? dst[i] * src[i] >> 7 : 63147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta 255 - ((255 - dst[i]) * (255 - src[i]) >> 7); 63247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta } 63347fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 63447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta return result; 6353dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 6363dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 6373dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case RED: 6383dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 6393dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 64047fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 6413dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 6423dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta src[0], 6433dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[1], 6443dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[2], 6453dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 6463dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 6473dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 6483dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 6493dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case REFLECT: 6503dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 6513dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 65247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 6533dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 6543dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta src[0] == 255 ? 255 : Math.min(255, dst[0] * dst[0] / (255 - src[0])), 6553dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta src[1] == 255 ? 255 : Math.min(255, dst[1] * dst[1] / (255 - src[1])), 6563dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta src[2] == 255 ? 255 : Math.min(255, dst[2] * dst[2] / (255 - src[2])), 6573dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 6583dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 6593dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 6603dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 6613dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case SATURATION: 6623dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 6633dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 66447fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 6653dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float[] srcHSL = new float[3]; 6663dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta RGBtoHSL(src[0], src[1], src[2], srcHSL); 6673dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta float[] dstHSL = new float[3]; 6683dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta RGBtoHSL(dst[0], dst[1], dst[2], dstHSL); 6693dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 6703dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta HSLtoRGB(dstHSL[0], srcHSL[1], dstHSL[2], result); 6713dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta result[3] = Math.min(255, src[3] + dst[3]); 6723dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 6733dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return result; 6743dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 6753dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 6763dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case SCREEN: 6773dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 6783dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 67947fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 6803dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 6813dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 255 - ((255 - src[0]) * (255 - dst[0]) >> 8), 6823dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 255 - ((255 - src[1]) * (255 - dst[1]) >> 8), 6833dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta 255 - ((255 - src[2]) * (255 - dst[2]) >> 8), 6843dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 6853dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 6863dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 6873dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 6883dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case SOFT_BURN: 6893dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 6903dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 69147fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 6923dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 6933dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[0] + src[0] < 256 ? 6943dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta (dst[0] == 255 ? 255 : 6953dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, (src[0] << 7) / (255 - dst[0]))) : 6963dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, 255 - (((255 - dst[0]) << 7) / src[0])), 6973dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[1] + src[1] < 256 ? 6983dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta (dst[1] == 255 ? 255 : 6993dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, (src[1] << 7) / (255 - dst[1]))) : 7003dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, 255 - (((255 - dst[1]) << 7) / src[1])), 7013dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[2] + src[2] < 256 ? 7023dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta (dst[2] == 255 ? 255 : 7033dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, (src[2] << 7) / (255 - dst[2]))) : 7043dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, 255 - (((255 - dst[2]) << 7) / src[2])), 7053dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 7063dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 7073dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 7083dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 7093dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case SOFT_DODGE: 7103dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 7113dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 71247fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 7133dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 7143dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[0] + src[0] < 256 ? 7153dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta (src[0] == 255 ? 255 : 7163dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, (dst[0] << 7) / (255 - src[0]))) : 7173dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, 255 - (((255 - src[0]) << 7) / dst[0])), 7183dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[1] + src[1] < 256 ? 7193dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta (src[1] == 255 ? 255 : 7203dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, (dst[1] << 7) / (255 - src[1]))) : 7213dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, 255 - (((255 - src[1]) << 7) / dst[1])), 7223dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta dst[2] + src[2] < 256 ? 7233dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta (src[2] == 255 ? 255 : 7243dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, (dst[2] << 7) / (255 - src[2]))) : 7253dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, 255 - (((255 - src[2]) << 7) / dst[2])), 7263dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 7273dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 7283dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 7293dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 7303dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case SOFT_LIGHT: 7313dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta break; 7323dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case STAMP: 7333dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 7343dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 73547fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 7363dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 7373dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, Math.min(255, dst[0] + 2 * src[0] - 256)), 7383dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, Math.min(255, dst[1] + 2 * src[1] - 256)), 7393dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, Math.min(255, dst[2] + 2 * src[2] - 256)), 7403dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 7413dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 7423dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 7433dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 7443dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta case SUBTRACT: 7453dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new Blender() { 7463dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta @Override 74747fa5c920d6eb93e435794544b96a0e4ede4403aDeepanshu Gupta public int[] blend(int[] src, int[] dst, int[] result) { 7483dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta return new int[] { 7493dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, src[0] + dst[0] - 256), 7503dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, src[1] + dst[1] - 256), 7513dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.max(0, src[2] + dst[2] - 256), 7523dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta Math.min(255, src[3] + dst[3]) 7533dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 7543dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 7553dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta }; 7563dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 7573dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta throw new IllegalArgumentException("Blender not implement for " + 7583dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta composite.getMode().name()); 7593dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 7603dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta } 7613dfc1c21d58a7a6764a436cbf5c3c8ba09db45e5Deepanshu Gupta} 762