1 /* 2 * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.awt.image; 27 28 import java.util.Hashtable; 29 30 /** 31 * This class implements a filter for the set of interface methods that 32 * are used to deliver data from an ImageProducer to an ImageConsumer. 33 * It is meant to be used in conjunction with a FilteredImageSource 34 * object to produce filtered versions of existing images. It is a 35 * base class that provides the calls needed to implement a "Null filter" 36 * which has no effect on the data being passed through. Filters should 37 * subclass this class and override the methods which deal with the 38 * data that needs to be filtered and modify it as necessary. 39 * 40 * @see FilteredImageSource 41 * @see ImageConsumer 42 * 43 * @author Jim Graham 44 */ 45 public class ImageFilter implements ImageConsumer, Cloneable { 46 /** 47 * The consumer of the particular image data stream for which this 48 * instance of the ImageFilter is filtering data. It is not 49 * initialized during the constructor, but rather during the 50 * getFilterInstance() method call when the FilteredImageSource 51 * is creating a unique instance of this object for a particular 52 * image data stream. 53 * @see #getFilterInstance 54 * @see ImageConsumer 55 */ 56 protected ImageConsumer consumer; 57 58 /** 59 * Returns a unique instance of an ImageFilter object which will 60 * actually perform the filtering for the specified ImageConsumer. 61 * The default implementation just clones this object. 62 * <p> 63 * Note: This method is intended to be called by the ImageProducer 64 * of the Image whose pixels are being filtered. Developers using 65 * this class to filter pixels from an image should avoid calling 66 * this method directly since that operation could interfere 67 * with the filtering operation. 68 * @param ic the specified {@code ImageConsumer} 69 * @return an {@code ImageFilter} used to perform the 70 * filtering for the specified {@code ImageConsumer}. 71 */ 72 public ImageFilter getFilterInstance(ImageConsumer ic) { 73 ImageFilter instance = (ImageFilter) clone(); 74 instance.consumer = ic; 75 return instance; 76 } 77 78 /** 79 * Returns a unique instance of an ImageFilter object used to perform 80 * the filtering for an image which size is scaled (relative to 81 * the original image size). 82 * The default implementation just clones this object. 83 * <p> 84 * @param scaleX the specified scale factor fox x-axis 85 * @param scaleY the specified scale factor fox y-axis 86 * @return an {@code ImageFilter} used to perform the 87 * filtering for scaled images. 88 */ 89 public ImageFilter getScaledFilterInstance(double scaleX, double scaleY) { 90 return (ImageFilter) clone(); 91 } 92 93 /** 94 * Filters the information provided in the setDimensions method 95 * of the ImageConsumer interface. 96 * <p> 97 * Note: This method is intended to be called by the ImageProducer 98 * of the Image whose pixels are being filtered. Developers using 99 * this class to filter pixels from an image should avoid calling 100 * this method directly since that operation could interfere 101 * with the filtering operation. 102 * @see ImageConsumer#setDimensions 103 */ 104 public void setDimensions(int width, int height) { 105 consumer.setDimensions(width, height); 106 } 107 108 /** 109 * Passes the properties from the source object along after adding a 110 * property indicating the stream of filters it has been run through. 111 * <p> 112 * Note: This method is intended to be called by the ImageProducer 113 * of the Image whose pixels are being filtered. Developers using 114 * this class to filter pixels from an image should avoid calling 115 * this method directly since that operation could interfere 116 * with the filtering operation. 117 * 118 * @param props the properties from the source object 119 * @exception NullPointerException if {@code props} is null 120 */ 121 public void setProperties(Hashtable<?,?> props) { 122 @SuppressWarnings("unchecked") 123 Hashtable<Object,Object> p = (Hashtable<Object,Object>)props.clone(); 124 Object o = p.get("filters"); 125 if (o == null) { 126 p.put("filters", toString()); 127 } else if (o instanceof String) { 128 p.put("filters", ((String) o)+toString()); 129 } 130 consumer.setProperties(p); 131 } 132 133 /** 134 * Filter the information provided in the setColorModel method 135 * of the ImageConsumer interface. 136 * <p> 137 * Note: This method is intended to be called by the ImageProducer 138 * of the Image whose pixels are being filtered. Developers using 139 * this class to filter pixels from an image should avoid calling 140 * this method directly since that operation could interfere 141 * with the filtering operation. 142 * @see ImageConsumer#setColorModel 143 */ 144 public void setColorModel(ColorModel model) { 145 consumer.setColorModel(model); 146 } 147 148 /** 149 * Filters the information provided in the setHints method 150 * of the ImageConsumer interface. 151 * <p> 152 * Note: This method is intended to be called by the ImageProducer 153 * of the Image whose pixels are being filtered. Developers using 154 * this class to filter pixels from an image should avoid calling 155 * this method directly since that operation could interfere 156 * with the filtering operation. 157 * @see ImageConsumer#setHints 158 */ 159 public void setHints(int hints) { 160 consumer.setHints(hints); 161 } 162 163 /** 164 * Filters the information provided in the setPixels method of the 165 * ImageConsumer interface which takes an array of bytes. 166 * <p> 167 * Note: This method is intended to be called by the ImageProducer 168 * of the Image whose pixels are being filtered. Developers using 169 * this class to filter pixels from an image should avoid calling 170 * this method directly since that operation could interfere 171 * with the filtering operation. 172 * @see ImageConsumer#setPixels 173 */ 174 public void setPixels(int x, int y, int w, int h, 175 ColorModel model, byte pixels[], int off, 176 int scansize) { 177 consumer.setPixels(x, y, w, h, model, pixels, off, scansize); 178 } 179 180 /** 181 * Filters the information provided in the setPixels method of the 182 * ImageConsumer interface which takes an array of integers. 183 * <p> 184 * Note: This method is intended to be called by the ImageProducer 185 * of the Image whose pixels are being filtered. Developers using 186 * this class to filter pixels from an image should avoid calling 187 * this method directly since that operation could interfere 188 * with the filtering operation. 189 * @see ImageConsumer#setPixels 190 */ 191 public void setPixels(int x, int y, int w, int h, 192 ColorModel model, int pixels[], int off, 193 int scansize) { 194 consumer.setPixels(x, y, w, h, model, pixels, off, scansize); 195 } 196 197 /** 198 * Filters the information provided in the imageComplete method of 199 * the ImageConsumer interface. 200 * <p> 201 * Note: This method is intended to be called by the ImageProducer 202 * of the Image whose pixels are being filtered. Developers using 203 * this class to filter pixels from an image should avoid calling 204 * this method directly since that operation could interfere 205 * with the filtering operation. 206 * @see ImageConsumer#imageComplete 207 */ 208 public void imageComplete(int status) { 209 consumer.imageComplete(status); 210 } 211 212 /** 213 * Responds to a request for a TopDownLeftRight (TDLR) ordered resend 214 * of the pixel data from an {@code ImageConsumer}. 215 * When an {@code ImageConsumer} being fed 216 * by an instance of this {@code ImageFilter} 217 * requests a resend of the data in TDLR order, 218 * the {@code FilteredImageSource} 219 * invokes this method of the {@code ImageFilter}. 220 * 221 * <p> 222 * 223 * An {@code ImageFilter} subclass might override this method or not, 224 * depending on if and how it can send data in TDLR order. 225 * Three possibilities exist: 226 * 227 * <ul> 228 * <li> 229 * Do not override this method. 230 * This makes the subclass use the default implementation, 231 * which is to 232 * forward the request 233 * to the indicated {@code ImageProducer} 234 * using this filter as the requesting {@code ImageConsumer}. 235 * This behavior 236 * is appropriate if the filter can determine 237 * that it will forward the pixels 238 * in TDLR order if its upstream producer object 239 * sends them in TDLR order. 240 * 241 * <li> 242 * Override the method to simply send the data. 243 * This is appropriate if the filter can handle the request itself — 244 * for example, 245 * if the generated pixels have been saved in some sort of buffer. 246 * 247 * <li> 248 * Override the method to do nothing. 249 * This is appropriate 250 * if the filter cannot produce filtered data in TDLR order. 251 * </ul> 252 * 253 * @see ImageProducer#requestTopDownLeftRightResend 254 * @param ip the ImageProducer that is feeding this instance of 255 * the filter - also the ImageProducer that the request should be 256 * forwarded to if necessary 257 * @exception NullPointerException if {@code ip} is null 258 */ 259 public void resendTopDownLeftRight(ImageProducer ip) { 260 ip.requestTopDownLeftRightResend(this); 261 } 262 263 /** 264 * Clones this object. 265 */ 266 public Object clone() { 267 try { 268 return super.clone(); 269 } catch (CloneNotSupportedException e) { 270 // this shouldn't happen, since we are Cloneable 271 throw new InternalError(e); 272 } 273 } 274 }