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 import java.awt.image.ColorModel; 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 flips images or rotates by multiples of 90 degrees. 030 */ 031 public class FlipFilter extends AbstractBufferedImageOp implements DynFiltering { 032 033 /** 034 * Flip the image horizontally. 035 */ 036 public static final int FLIP_H = 1; 037 038 /** 039 * Flip the image vertically. 040 */ 041 public static final int FLIP_V = 2; 042 043 /** 044 * Flip the image horizontally and vertically. 045 */ 046 public static final int FLIP_HV = 3; 047 048 /** 049 * Rotate the image 90 degrees clockwise. 050 */ 051 public static final int FLIP_90CW = 4; 052 053 /** 054 * Rotate the image 90 degrees counter-clockwise. 055 */ 056 public static final int FLIP_90CCW = 5; 057 058 /** 059 * Rotate the image 180 degrees. 060 */ 061 public static final int FLIP_180 = 6; 062 063 private int operation; 064 private int width, height; 065 private int newWidth, newHeight; 066 067 /** 068 * Construct a FlipFilter which flips horizontally and vertically. 069 */ 070 public FlipFilter() { 071 this(FLIP_HV); 072 } 073 074 /** 075 * Construct a FlipFilter. 076 * @param operation the filter operation 077 */ 078 public FlipFilter(int operation) { 079 this.operation = operation; 080 } 081 082 /** 083 * Set the filter operation. 084 * @param operation the filter operation 085 * @see #getOperation 086 */ 087 public void setOperation(int operation) { 088 this.operation = operation; 089 } 090 091 /** 092 * Get the filter operation. 093 * @return the filter operation 094 * @see #setOperation 095 */ 096 public int getOperation() { 097 return operation; 098 } 099 100 public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 101 int width = src.getWidth(); 102 int height = src.getHeight(); 103 //int type = src.getType(); 104 //WritableRaster srcRaster = 105 src.getRaster(); 106 107 int[] inPixels = getRGB( src, 0, 0, width, height, null ); 108 109 //int x = 0, y = 0; 110 int w = width; 111 int h = height; 112 113 //int newX = 0; 114 //int newY = 0; 115 int newW = w; 116 int newH = h; 117 switch (operation) { 118 case FLIP_H: 119 //newX = width - (x + w); 120 break; 121 case FLIP_V: 122 //newY = height - (y + h); 123 break; 124 case FLIP_HV: 125 newW = h; 126 newH = w; 127 //newX = y; 128 //newY = x; 129 break; 130 case FLIP_90CW: 131 newW = h; 132 newH = w; 133 //newX = height - (y + h); 134 //newY = x; 135 break; 136 case FLIP_90CCW: 137 newW = h; 138 newH = w; 139 //newX = y; 140 //newY = width - (x + w); 141 break; 142 case FLIP_180: 143 //newX = width - (x + w); 144 //newY = height - (y + h); 145 break; 146 } 147 148 int[] newPixels = new int[newW * newH]; 149 150 for (int row = 0; row < h; row++) { 151 for (int col = 0; col < w; col++) { 152 int index = row * width + col; 153 int newRow = row; 154 int newCol = col; 155 switch (operation) { 156 case FLIP_H: 157 newCol = w - col - 1; 158 break; 159 case FLIP_V: 160 newRow = h - row - 1; 161 break; 162 case FLIP_HV: 163 newRow = col; 164 newCol = row; 165 break; 166 case FLIP_90CW: 167 newRow = col; 168 newCol = h - row - 1;; 169 break; 170 case FLIP_90CCW: 171 newRow = w - col - 1; 172 newCol = row; 173 break; 174 case FLIP_180: 175 newRow = h - row - 1; 176 newCol = w - col - 1; 177 break; 178 } 179 int newIndex = newRow * newW + newCol; 180 newPixels[newIndex] = inPixels[index]; 181 } 182 } 183 184 if ( dst == null ) { 185 ColorModel dstCM = src.getColorModel(); 186 dst = new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(newW, newH), dstCM.isAlphaPremultiplied(), null); 187 } 188 //WritableRaster dstRaster = 189 dst.getRaster(); 190 setRGB( dst, 0, 0, newW, newH, newPixels ); 191 192 return dst; 193 } 194 195 public String toString() { 196 switch (operation) { 197 case FLIP_H: 198 return "Flip Horizontal"; 199 case FLIP_V: 200 return "Flip Vertical"; 201 case FLIP_HV: 202 return "Flip Diagonal"; 203 case FLIP_90CW: 204 return "Rotate 90"; 205 case FLIP_90CCW: 206 return "Rotate -90"; 207 case FLIP_180: 208 return "Rotate 180"; 209 } 210 return "Flip"; 211 } 212 public BufferedImage filter(BufferedImage src, Struct parameters) throws PageException {BufferedImage dst=ImageUtil.createBufferedImage(src); 213 Object o; 214 if((o=parameters.removeEL(KeyImpl.init("Operation")))!=null)setOperation(ImageFilterUtil.toIntValue(o,"Operation")); 215 216 // check for arguments not supported 217 if(parameters.size()>0) { 218 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 [Operation]"); 219 } 220 221 return filter(src, dst); 222 } 223 }