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.Rectangle; 018 import java.awt.image.BufferedImage; 019 020 import railo.runtime.engine.ThreadLocalPageContext; 021 import railo.runtime.exp.FunctionException; 022 import railo.runtime.exp.PageException; 023 import railo.runtime.img.ImageUtil; 024 import railo.runtime.type.KeyImpl; 025 import railo.runtime.type.Struct; 026 import railo.runtime.type.util.CollectionUtil; 027 028 /** 029 * A filter which performs one round of the game of Life on an image. 030 */ 031 public class LifeFilter extends BinaryFilter implements DynFiltering { 032 033 public LifeFilter() { 034 } 035 036 protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) { 037 int index = 0; 038 int[] outPixels = new int[width * height]; 039 040 for (int y = 0; y < height; y++) { 041 for (int x = 0; x < width; x++) { 042 //int r = 0, g = 0, b = 0; 043 int pixel = inPixels[y*width+x]; 044 //int a = pixel & 0xff000000; 045 int neighbours = 0; 046 047 for (int row = -1; row <= 1; row++) { 048 int iy = y+row; 049 int ioffset; 050 if (0 <= iy && iy < height) { 051 ioffset = iy*width; 052 for (int col = -1; col <= 1; col++) { 053 int ix = x+col; 054 if (!(row == 0 && col == 0) && 0 <= ix && ix < width) { 055 int rgb = inPixels[ioffset+ix]; 056 if (blackFunction.isBlack(rgb)) 057 neighbours++; 058 } 059 } 060 } 061 } 062 063 if (blackFunction.isBlack(pixel)) 064 outPixels[index++] = (neighbours == 2 || neighbours == 3) ? pixel : 0xffffffff; 065 else 066 outPixels[index++] = neighbours == 3 ? 0xff000000 : pixel; 067 } 068 069 } 070 return outPixels; 071 } 072 073 public String toString() { 074 return "Binary/Life"; 075 } 076 077 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src); 078 Object o; 079 if((o=parameters.removeEL(KeyImpl.init("Iterations")))!=null)setIterations(ImageFilterUtil.toIntValue(o,"Iterations")); 080 if((o=parameters.removeEL(KeyImpl.init("Colormap")))!=null)setColormap(ImageFilterUtil.toColormap(o,"Colormap")); 081 if((o=parameters.removeEL(KeyImpl.init("NewColor")))!=null)setNewColor(ImageFilterUtil.toColorRGB(o,"NewColor")); 082 083 // check for arguments not supported 084 if(parameters.size()>0) { 085 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 [Iterations, Colormap, NewColor, BlackFunction]"); 086 } 087 088 return filter(src, dst); 089 } 090 } 091