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.type.KeyImpl;
023    import railo.runtime.type.Struct;
024    import railo.runtime.type.util.CollectionUtil;
025    
026    /**
027     * This filter diffuses an image by moving its pixels in random directions.
028     */
029    public class DiffuseFilter extends TransformFilter  implements DynFiltering {
030    
031            private float[] sinTable, cosTable;
032            private float scale = 4;
033            
034            public DiffuseFilter() {
035                    super(ConvolveFilter.CLAMP_EDGES);
036            }
037            
038            /**
039         * Specifies the scale of the texture.
040         * @param scale the scale of the texture.
041         * @min-value 1
042         * @max-value 100+
043         * @see #getScale
044         */
045            public void setScale(float scale) {
046                    this.scale = scale;
047            }
048    
049            /**
050         * Returns the scale of the texture.
051         * @return the scale of the texture.
052         * @see #setScale
053         */
054            public float getScale() {
055                    return scale;
056            }
057    
058            protected void transformInverse(int x, int y, float[] out) {
059                    int angle = (int)(Math.random() * 255);
060                    float distance = (float)Math.random();
061                    out[0] = x + distance * sinTable[angle];
062                    out[1] = y + distance * cosTable[angle];
063            }
064    
065        public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
066                    sinTable = new float[256];
067                    cosTable = new float[256];
068                    for (int i = 0; i < 256; i++) {
069                            float angle = ImageMath.TWO_PI*i/256f;
070                            sinTable[i] = (float)(scale*Math.sin(angle));
071                            cosTable[i] = (float)(scale*Math.cos(angle));
072                    }
073                    return super.filter( src, dst );
074            }
075    
076            public String toString() {
077                    return "Distort/Diffuse...";
078            }
079            public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=null;//ImageUtil.createBufferedImage(src);
080                    Object o;
081                    if((o=parameters.removeEL(KeyImpl.init("Scale")))!=null)setScale(ImageFilterUtil.toFloatValue(o,"Scale"));
082                    if((o=parameters.removeEL(KeyImpl.init("EdgeAction")))!=null)setEdgeAction(ImageFilterUtil.toString(o,"EdgeAction"));
083                    if((o=parameters.removeEL(KeyImpl.init("Interpolation")))!=null)setInterpolation(ImageFilterUtil.toString(o,"Interpolation"));
084    
085                    // check for arguments not supported
086                    if(parameters.size()>0) {
087                            throw new FunctionException(ThreadLocalPageContext.get(), "ImageFilter", 3, "parameters", "the parameter"+(parameters.size()>1?"s":"")+" ["+CollectionUtil.getKeyList(parameters,", ")+"] "+(parameters.size()>1?"are":"is")+" not allowed, only the following parameters are supported [Scale, EdgeAction, Interpolation]");
088                    }
089    
090                    return filter(src, dst);
091            }
092    }