001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019/*
020*
021
022Licensed under the Apache License, Version 2.0 (the "License");
023you may not use this file except in compliance with the License.
024You may obtain a copy of the License at
025
026   http://www.apache.org/licenses/LICENSE-2.0
027
028Unless required by applicable law or agreed to in writing, software
029distributed under the License is distributed on an "AS IS" BASIS,
030WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
031See the License for the specific language governing permissions and
032limitations under the License.
033*/
034
035package lucee.runtime.img.filter;import java.awt.image.BufferedImage;
036
037import lucee.runtime.engine.ThreadLocalPageContext;
038import lucee.runtime.exp.FunctionException;
039import lucee.runtime.exp.PageException;
040import lucee.runtime.type.KeyImpl;
041import lucee.runtime.type.Struct;
042import lucee.runtime.type.util.CollectionUtil;
043
044/**
045 * This filter diffuses an image by moving its pixels in random directions.
046 */
047public class DiffuseFilter extends TransformFilter  implements DynFiltering {
048
049        private float[] sinTable, cosTable;
050        private float scale = 4;
051        
052        public DiffuseFilter() {
053                super(ConvolveFilter.CLAMP_EDGES);
054        }
055        
056        /**
057     * Specifies the scale of the texture.
058     * @param scale the scale of the texture.
059     * @min-value 1
060     * @max-value 100+
061     * @see #getScale
062     */
063        public void setScale(float scale) {
064                this.scale = scale;
065        }
066
067        /**
068     * Returns the scale of the texture.
069     * @return the scale of the texture.
070     * @see #setScale
071     */
072        public float getScale() {
073                return scale;
074        }
075
076        protected void transformInverse(int x, int y, float[] out) {
077                int angle = (int)(Math.random() * 255);
078                float distance = (float)Math.random();
079                out[0] = x + distance * sinTable[angle];
080                out[1] = y + distance * cosTable[angle];
081        }
082
083    public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
084                sinTable = new float[256];
085                cosTable = new float[256];
086                for (int i = 0; i < 256; i++) {
087                        float angle = ImageMath.TWO_PI*i/256f;
088                        sinTable[i] = (float)(scale*Math.sin(angle));
089                        cosTable[i] = (float)(scale*Math.cos(angle));
090                }
091                return super.filter( src, dst );
092        }
093
094        public String toString() {
095                return "Distort/Diffuse...";
096        }
097        public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=null;//ImageUtil.createBufferedImage(src);
098                Object o;
099                if((o=parameters.removeEL(KeyImpl.init("Scale")))!=null)setScale(ImageFilterUtil.toFloatValue(o,"Scale"));
100                if((o=parameters.removeEL(KeyImpl.init("EdgeAction")))!=null)setEdgeAction(ImageFilterUtil.toString(o,"EdgeAction"));
101                if((o=parameters.removeEL(KeyImpl.init("Interpolation")))!=null)setInterpolation(ImageFilterUtil.toString(o,"Interpolation"));
102
103                // check for arguments not supported
104                if(parameters.size()>0) {
105                        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]");
106                }
107
108                return filter(src, dst);
109        }
110}