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.img.ImageUtil;
041import lucee.runtime.type.KeyImpl;
042import lucee.runtime.type.Struct;
043import lucee.runtime.type.util.CollectionUtil;
044
045
046
047/**
048 * A filter which performs a threshold operation on an image.
049 */
050public class ThresholdFilter extends PointFilter  implements DynFiltering {
051
052        private int lowerThreshold;
053        private int lowerThreshold3;
054        private int upperThreshold;
055        private int upperThreshold3;
056        private int white = 0xffffff;
057        private int black = 0x000000;
058        
059        /**
060     * Construct a ThresholdFilter.
061     */
062    public ThresholdFilter() {
063                this(127);
064        }
065
066        /**
067     * Construct a ThresholdFilter.
068     * @param t the threshold value
069     */
070        public ThresholdFilter(int t) {
071                setLowerThreshold(t);
072                setUpperThreshold(t);
073        }
074
075        /**
076     * Set the lower threshold value.
077     * @param lowerThreshold the threshold value
078     * @see #getLowerThreshold
079     */
080        public void setLowerThreshold(int lowerThreshold) {
081                this.lowerThreshold = lowerThreshold;
082                lowerThreshold3 = lowerThreshold*3;
083        }
084        
085        /**
086     * Get the lower threshold value.
087     * @return the threshold value
088     * @see #setLowerThreshold
089     */
090        public int getLowerThreshold() {
091                return lowerThreshold;
092        }
093        
094        /**
095     * Set the upper threshold value.
096     * @param upperThreshold the threshold value
097     * @see #getUpperThreshold
098     */
099        public void setUpperThreshold(int upperThreshold) {
100                this.upperThreshold = upperThreshold;
101                upperThreshold3 = upperThreshold*3;
102        }
103
104        /**
105     * Get the upper threshold value.
106     * @return the threshold value
107     * @see #setUpperThreshold
108     */
109        public int getUpperThreshold() {
110                return upperThreshold;
111        }
112
113        /**
114     * Set the color to be used for pixels above the upper threshold.
115     * @param white the color
116     * @see #getWhite
117     */
118        public void setWhite(int white) {
119                this.white = white;
120        }
121
122        /**
123     * Get the color to be used for pixels above the upper threshold.
124     * @return the color
125     * @see #setWhite
126     */
127        public int getWhite() {
128                return white;
129        }
130
131        /**
132     * Set the color to be used for pixels below the lower threshold.
133     * @param black the color
134     * @see #getBlack
135     */
136        public void setBlack(int black) {
137                this.black = black;
138        }
139
140        /**
141     * Set the color to be used for pixels below the lower threshold.
142     * @return the color
143     * @see #setBlack
144     */
145        public int getBlack() {
146                return black;
147        }
148
149        public int filterRGB(int x, int y, int rgb) {
150                int a = rgb & 0xff000000;
151                int r = (rgb >> 16) & 0xff;
152                int g = (rgb >> 8) & 0xff;
153                int b = rgb & 0xff;
154                int l = r + g + b;
155                if (l < lowerThreshold3)
156                        return a | black;
157                else if (l > upperThreshold3)
158                        return a | white;
159                return rgb;
160        }
161
162        public String toString() {
163                return "Stylize/Threshold...";
164        }
165        public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src);
166                Object o;
167                if((o=parameters.removeEL(KeyImpl.init("White")))!=null)setWhite(ImageFilterUtil.toColorRGB(o,"White"));
168                if((o=parameters.removeEL(KeyImpl.init("Black")))!=null)setBlack(ImageFilterUtil.toColorRGB(o,"Black"));
169                if((o=parameters.removeEL(KeyImpl.init("LowerThreshold")))!=null)setLowerThreshold(ImageFilterUtil.toIntValue(o,"LowerThreshold"));
170                if((o=parameters.removeEL(KeyImpl.init("UpperThreshold")))!=null)setUpperThreshold(ImageFilterUtil.toIntValue(o,"UpperThreshold"));
171                if((o=parameters.removeEL(KeyImpl.init("Dimensions")))!=null){
172                        int[] dim=ImageFilterUtil.toDimensions(o,"Dimensions");
173                        setDimensions(dim[0],dim[1]);
174                }
175
176                // check for arguments not supported
177                if(parameters.size()>0) {
178                        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 [White, Black, LowerThreshold, UpperThreshold, Dimensions]");
179                }
180
181                return filter(src, dst);
182        }
183}