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