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.Struct; 025 import railo.runtime.type.util.CollectionUtil; 026 027 /** 028 * A filter which performs reduces noise by looking at each pixel's 8 neighbours, and if it's a minimum or maximum, 029 * replacing it by the next minimum or maximum of the neighbours. 030 */ 031 public class ReduceNoiseFilter extends WholeImageFilter implements DynFiltering { 032 033 public ReduceNoiseFilter() { 034 } 035 036 private int smooth(int[] v) { 037 int minindex = 0, maxindex = 0, min = Integer.MAX_VALUE, max = Integer.MIN_VALUE; 038 039 for (int i = 0; i < 9; i++) { 040 if ( i != 4 ) { 041 if (v[i] < min) { 042 min = v[i]; 043 minindex = i; 044 } 045 if (v[i] > max) { 046 max = v[i]; 047 maxindex = i; 048 } 049 } 050 } 051 if ( v[4] < min ) 052 return v[minindex]; 053 if ( v[4] > max ) 054 return v[maxindex]; 055 return v[4]; 056 } 057 058 protected int[] filterPixels( int width, int height, int[] inPixels, Rectangle transformedSpace ) { 059 int index = 0; 060 int[] r = new int[9]; 061 int[] g = new int[9]; 062 int[] b = new int[9]; 063 int[] outPixels = new int[width * height]; 064 065 for (int y = 0; y < height; y++) { 066 for (int x = 0; x < width; x++) { 067 int k = 0; 068 int irgb = inPixels[index]; 069 int ir = (irgb >> 16) & 0xff; 070 int ig = (irgb >> 8) & 0xff; 071 int ib = irgb & 0xff; 072 for (int dy = -1; dy <= 1; dy++) { 073 int iy = y+dy; 074 if (0 <= iy && iy < height) { 075 int ioffset = iy*width; 076 for (int dx = -1; dx <= 1; dx++) { 077 int ix = x+dx; 078 if (0 <= ix && ix < width) { 079 int rgb = inPixels[ioffset+ix]; 080 r[k] = (rgb >> 16) & 0xff; 081 g[k] = (rgb >> 8) & 0xff; 082 b[k] = rgb & 0xff; 083 } else { 084 r[k] = ir; 085 g[k] = ig; 086 b[k] = ib; 087 } 088 k++; 089 } 090 } else { 091 for (int dx = -1; dx <= 1; dx++) { 092 r[k] = ir; 093 g[k] = ig; 094 b[k] = ib; 095 k++; 096 } 097 } 098 } 099 outPixels[index] = (inPixels[index] & 0xff000000) | (smooth(r) << 16) | (smooth(g) << 8) | smooth(b); 100 index++; 101 } 102 } 103 return outPixels; 104 } 105 106 public String toString() { 107 return "Blur/Smooth"; 108 } 109 110 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src); 111 //Object o; 112 113 // check for arguments not supported 114 if(parameters.size()>0) { 115 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 []"); 116 } 117 118 return filter(src, dst); 119 } 120 } 121