001    /*
002    *
003    
004    Licensed under the Apache License, Version 2.0 (the "License");
005    you may not use this file except in compliance with the License.
006    You may obtain a copy of the License at
007    
008       http://www.apache.org/licenses/LICENSE-2.0
009    
010    Unless required by applicable law or agreed to in writing, software
011    distributed under the License is distributed on an "AS IS" BASIS,
012    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013    See the License for the specific language governing permissions and
014    limitations under the License.
015    */
016    
017    package railo.runtime.img.filter;import java.awt.image.BufferedImage;
018    
019    import railo.runtime.engine.ThreadLocalPageContext;
020    import railo.runtime.exp.FunctionException;
021    import railo.runtime.exp.PageException;
022    import railo.runtime.img.ImageUtil;
023    import railo.runtime.type.KeyImpl;
024    import railo.runtime.type.List;
025    import railo.runtime.type.Struct;
026    
027    /**
028     * A filter which allows the red, green and blue channels of an image to be mixed into each other.
029     */
030    public class ChannelMixFilter extends PointFilter  implements DynFiltering {
031            
032            private int blueGreen, redBlue, greenRed;
033            private int intoR, intoG, intoB;
034            
035            public ChannelMixFilter() {
036                    canFilterIndexColorModel = true;
037            }
038    
039            public void setBlueGreen(int blueGreen) {
040                    this.blueGreen = blueGreen;
041            }
042    
043            public int getBlueGreen() {
044                    return blueGreen;
045            }
046    
047            public void setRedBlue(int redBlue) {
048                    this.redBlue = redBlue;
049            }
050    
051            public int getRedBlue() {
052                    return redBlue;
053            }
054    
055            public void setGreenRed(int greenRed) {
056                    this.greenRed = greenRed;
057            }
058    
059            public int getGreenRed() {
060                    return greenRed;
061            }
062    
063            public void setIntoR(int intoR) {
064                    this.intoR = intoR;
065            }
066    
067            public int getIntoR() {
068                    return intoR;
069            }
070    
071            public void setIntoG(int intoG) {
072                    this.intoG = intoG;
073            }
074    
075            public int getIntoG() {
076                    return intoG;
077            }
078    
079            public void setIntoB(int intoB) {
080                    this.intoB = intoB;
081            }
082    
083            public int getIntoB() {
084                    return intoB;
085            }
086    
087            public int filterRGB(int x, int y, int rgb) {
088                    int a = rgb & 0xff000000;
089                    int r = (rgb >> 16) & 0xff;
090                    int g = (rgb >> 8) & 0xff;
091                    int b = rgb & 0xff;
092                    int nr = PixelUtils.clamp((intoR * (blueGreen*g+(255-blueGreen)*b)/255 + (255-intoR)*r)/255);
093                    int ng = PixelUtils.clamp((intoG * (redBlue*b+(255-redBlue)*r)/255 + (255-intoG)*g)/255);
094                    int nb = PixelUtils.clamp((intoB * (greenRed*r+(255-greenRed)*g)/255 + (255-intoB)*b)/255);
095                    return a | (nr << 16) | (ng << 8) | nb;
096            }
097    
098            public String toString() {
099                    return "Colors/Mix Channels...";
100            }
101            public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src);
102                    Object o;
103                    if((o=parameters.removeEL(KeyImpl.init("BlueGreen")))!=null)setBlueGreen(ImageFilterUtil.toIntValue(o,"BlueGreen"));
104                    if((o=parameters.removeEL(KeyImpl.init("RedBlue")))!=null)setRedBlue(ImageFilterUtil.toIntValue(o,"RedBlue"));
105                    if((o=parameters.removeEL(KeyImpl.init("GreenRed")))!=null)setGreenRed(ImageFilterUtil.toIntValue(o,"GreenRed"));
106                    if((o=parameters.removeEL(KeyImpl.init("IntoR")))!=null)setIntoR(ImageFilterUtil.toIntValue(o,"IntoR"));
107                    if((o=parameters.removeEL(KeyImpl.init("IntoG")))!=null)setIntoG(ImageFilterUtil.toIntValue(o,"IntoG"));
108                    if((o=parameters.removeEL(KeyImpl.init("IntoB")))!=null)setIntoB(ImageFilterUtil.toIntValue(o,"IntoB"));
109                    if((o=parameters.removeEL(KeyImpl.init("Dimensions")))!=null){
110                            int[] dim=ImageFilterUtil.toDimensions(o,"Dimensions");
111                            setDimensions(dim[0],dim[1]);
112                    }
113    
114                    // check for arguments not supported
115                    if(parameters.size()>0) {
116                            throw new FunctionException(ThreadLocalPageContext.get(), "ImageFilter", 3, "parameters", "the parameter"+(parameters.size()>1?"s":"")+" ["+List.arrayToList(parameters.keysAsString(),", ")+"] "+(parameters.size()>1?"are":"is")+" not allowed, only the following parameters are supported [BlueGreen, RedBlue, GreenRed, IntoR, IntoG, IntoB, Dimensions]");
117                    }
118    
119                    return filter(src, dst);
120            }
121    }
122