1 /* 2 * Copyright (c) 1995, 2011, 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</code> 69 * @return an <code>ImageFilter</code> used to perform the 70 * filtering for the specified <code>ImageConsumer</code>. 71 */ 72 public ImageFilter getFilterInstance(ImageConsumer ic) { 73 ImageFilter instance = (ImageFilter) clone(); 74 instance.consumer = ic; 75 return instance; 76 } 77 78 /** 79 * Filters the information provided in the setDimensions method 80 * of the ImageConsumer interface. 81 * <p> 82 * Note: This method is intended to be called by the ImageProducer 83 * of the Image whose pixels are being filtered. Developers using 84 * this class to filter pixels from an image should avoid calling 85 * this method directly since that operation could interfere 86 * with the filtering operation. 87 * @see ImageConsumer#setDimensions 88 */ 89 public void setDimensions(int width, int height) { 90 consumer.setDimensions(width, height); 91 } 92 93 /** 94 * Passes the properties from the source object along after adding a 95 * property indicating the stream of filters it has been run through. 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 * 103 * @param props the properties from the source object 104 * @exception NullPointerException if <code>props</code> is null 105 */ 106 public void setProperties(Hashtable<?,?> props) { 107 Hashtable<Object,Object> p = (Hashtable<Object,Object>)props.clone(); 108 Object o = p.get("filters"); 109 if (o == null) { 110 p.put("filters", toString()); 111 } else if (o instanceof String) { 112 p.put("filters", ((String) o)+toString()); 113 } 114 consumer.setProperties(p); 115 } 116 117 /** 118 * Filter the information provided in the setColorModel method 119 * of the ImageConsumer interface. 120 * <p> 121 * Note: This method is intended to be called by the ImageProducer 122 * of the Image whose pixels are being filtered. Developers using 123 * this class to filter pixels from an image should avoid calling 124 * this method directly since that operation could interfere 125 * with the filtering operation. 126 * @see ImageConsumer#setColorModel 127 */ 128 public void setColorModel(ColorModel model) { 129 consumer.setColorModel(model); 130 } 131 132 /** 133 * Filters the information provided in the setHints method 134 * of the ImageConsumer interface. 135 * <p> 136 * Note: This method is intended to be called by the ImageProducer 137 * of the Image whose pixels are being filtered. Developers using 138 * this class to filter pixels from an image should avoid calling 139 * this method directly since that operation could interfere 140 * with the filtering operation. 141 * @see ImageConsumer#setHints 142 */ 143 public void setHints(int hints) { 144 consumer.setHints(hints); 145 } 146 147 /** 148 * Filters the information provided in the setPixels method of the 149 * ImageConsumer interface which takes an array of bytes. 150 * <p> 151 * Note: This method is intended to be called by the ImageProducer 152 * of the Image whose pixels are being filtered. Developers using 153 * this class to filter pixels from an image should avoid calling 154 * this method directly since that operation could interfere 155 * with the filtering operation. 156 * @see ImageConsumer#setPixels 157 */ 158 public void setPixels(int x, int y, int w, int h, 159 ColorModel model, byte pixels[], int off, 160 int scansize) { 161 consumer.setPixels(x, y, w, h, model, pixels, off, scansize); 162 } 163 164 /** 165 * Filters the information provided in the setPixels method of the 166 * ImageConsumer interface which takes an array of integers. 167 * <p> 168 * Note: This method is intended to be called by the ImageProducer 169 * of the Image whose pixels are being filtered. Developers using 170 * this class to filter pixels from an image should avoid calling 171 * this method directly since that operation could interfere 172 * with the filtering operation. 173 * @see ImageConsumer#setPixels 174 */ 175 public void setPixels(int x, int y, int w, int h, 176 ColorModel model, int pixels[], int off, 177 int scansize) { 178 consumer.setPixels(x, y, w, h, model, pixels, off, scansize); 179 } 180 181 /** 182 * Filters the information provided in the imageComplete method of 183 * the ImageConsumer interface. 184 * <p> 185 * Note: This method is intended to be called by the ImageProducer 186 * of the Image whose pixels are being filtered. Developers using 187 * this class to filter pixels from an image should avoid calling 188 * this method directly since that operation could interfere 189 * with the filtering operation. 190 * @see ImageConsumer#imageComplete 191 */ 192 public void imageComplete(int status) { 193 consumer.imageComplete(status); 194 } 195 196 /** 197 * Responds to a request for a TopDownLeftRight (TDLR) ordered resend 198 * of the pixel data from an <code>ImageConsumer</code>. 199 * When an <code>ImageConsumer</code> being fed 200 * by an instance of this <code>ImageFilter</code> 201 * requests a resend of the data in TDLR order, 202 * the <code>FilteredImageSource</code> 203 * invokes this method of the <code>ImageFilter</code>. 204 * 205 * <p> 206 * 207 * An <code>ImageFilter</code> subclass might override this method or not, 208 * depending on if and how it can send data in TDLR order. 209 * Three possibilities exist: 210 * 211 * <ul> 212 * <li> 213 * Do not override this method. 214 * This makes the subclass use the default implementation, 215 * which is to 216 * forward the request 217 * to the indicated <code>ImageProducer</code> 218 * using this filter as the requesting <code>ImageConsumer</code>. 219 * This behavior 220 * is appropriate if the filter can determine 221 * that it will forward the pixels 222 * in TDLR order if its upstream producer object 223 * sends them in TDLR order. 224 * 225 * <li> 226 * Override the method to simply send the data. 227 * This is appropriate if the filter can handle the request itself — 228 * for example, 229 * if the generated pixels have been saved in some sort of buffer. 230 * 231 * <li> 232 * Override the method to do nothing. 233 * This is appropriate 234 * if the filter cannot produce filtered data in TDLR order. 235 * </ul> 236 * 237 * @see ImageProducer#requestTopDownLeftRightResend 238 * @param ip the ImageProducer that is feeding this instance of 239 * the filter - also the ImageProducer that the request should be 240 * forwarded to if necessary 241 * @exception NullPointerException if <code>ip</code> is null 242 */ 243 public void resendTopDownLeftRight(ImageProducer ip) { 244 ip.requestTopDownLeftRightResend(this); 245 } 246 247 /** 248 * Clones this object. 249 */ 250 public Object clone() { 251 try { 252 return super.clone(); 253 } catch (CloneNotSupportedException e) { 254 // this shouldn't happen, since we are Cloneable 255 throw new InternalError(e); 256 } 257 } 258 }