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