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