1 /* 2 * Copyright (c) 1995, 2003, 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.awt.Image; 29 import java.awt.image.ImageFilter; 30 import java.awt.image.ImageConsumer; 31 import java.awt.image.ImageProducer; 32 import java.util.Hashtable; 33 import java.awt.image.ColorModel; 34 35 /** 36 * This class is an implementation of the ImageProducer interface which 37 * takes an existing image and a filter object and uses them to produce 38 * image data for a new filtered version of the original image. 39 * Here is an example which filters an image by swapping the red and 40 * blue compents: 41 * <pre> 42 * 43 * Image src = getImage("doc:///demo/images/duke/T1.gif"); 44 * ImageFilter colorfilter = new RedBlueSwapFilter(); 45 * Image img = createImage(new FilteredImageSource(src.getSource(), 46 * colorfilter)); 47 * 48 * </pre> 49 * 50 * @see ImageProducer 51 * 52 * @author Jim Graham 53 */ 54 public class FilteredImageSource implements ImageProducer { 55 ImageProducer src; 56 ImageFilter filter; 57 58 /** 59 * Constructs an ImageProducer object from an existing ImageProducer 60 * and a filter object. 61 * @param orig the specified <code>ImageProducer</code> 62 * @param imgf the specified <code>ImageFilter</code> 63 * @see ImageFilter 64 * @see java.awt.Component#createImage 65 */ 66 public FilteredImageSource(ImageProducer orig, ImageFilter imgf) { 67 src = orig; 68 filter = imgf; 69 } 70 71 private Hashtable<ImageConsumer, ImageFilter> proxies; 72 73 /** 74 * Adds the specified <code>ImageConsumer</code> 75 * to the list of consumers interested in data for the filtered image. 76 * An instance of the original <code>ImageFilter</code> 77 * is created 78 * (using the filter's <code>getFilterInstance</code> method) 79 * to manipulate the image data 80 * for the specified <code>ImageConsumer</code>. 81 * The newly created filter instance 82 * is then passed to the <code>addConsumer</code> method 83 * of the original <code>ImageProducer</code>. 84 * 85 * <p> 86 * This method is public as a side effect 87 * of this class implementing 88 * the <code>ImageProducer</code> interface. 89 * It should not be called from user code, 90 * and its behavior if called from user code is unspecified. 91 * 92 * @param ic the consumer for the filtered image 93 * @see ImageConsumer 94 */ 95 public synchronized void addConsumer(ImageConsumer ic) { 96 if (proxies == null) { 97 proxies = new Hashtable<>(); 98 } 99 if (!proxies.containsKey(ic)) { 100 ImageFilter imgf = filter.getFilterInstance(ic); 101 proxies.put(ic, imgf); 102 src.addConsumer(imgf); 103 } 104 } 105 106 /** 107 * Determines whether an ImageConsumer is on the list of consumers 108 * currently interested in data for this image. 109 * 110 * <p> 111 * This method is public as a side effect 112 * of this class implementing 113 * the <code>ImageProducer</code> interface. 114 * It should not be called from user code, 115 * and its behavior if called from user code is unspecified. 116 * 117 * @param ic the specified <code>ImageConsumer</code> 118 * @return true if the ImageConsumer is on the list; false otherwise 119 * @see ImageConsumer 120 */ 121 public synchronized boolean isConsumer(ImageConsumer ic) { 122 return (proxies != null && proxies.containsKey(ic)); 123 } 124 125 /** 126 * Removes an ImageConsumer from the list of consumers interested in 127 * data for this image. 128 * 129 * <p> 130 * This method is public as a side effect 131 * of this class implementing 132 * the <code>ImageProducer</code> interface. 133 * It should not be called from user code, 134 * and its behavior if called from user code is unspecified. 135 * 136 * @see ImageConsumer 137 */ 138 public synchronized void removeConsumer(ImageConsumer ic) { 139 if (proxies != null) { 140 ImageFilter imgf = (ImageFilter) proxies.get(ic); 141 if (imgf != null) { 142 src.removeConsumer(imgf); 143 proxies.remove(ic); 144 if (proxies.isEmpty()) { 145 proxies = null; 146 } 147 } 148 } 149 } 150 151 /** 152 * Starts production of the filtered image. 153 * If the specified <code>ImageConsumer</code> 154 * isn't already a consumer of the filtered image, 155 * an instance of the original <code>ImageFilter</code> 156 * is created 157 * (using the filter's <code>getFilterInstance</code> method) 158 * to manipulate the image data 159 * for the <code>ImageConsumer</code>. 160 * The filter instance for the <code>ImageConsumer</code> 161 * is then passed to the <code>startProduction</code> method 162 * of the original <code>ImageProducer</code>. 163 * 164 * <p> 165 * This method is public as a side effect 166 * of this class implementing 167 * the <code>ImageProducer</code> interface. 168 * It should not be called from user code, 169 * and its behavior if called from user code is unspecified. 170 * 171 * @param ic the consumer for the filtered image 172 * @see ImageConsumer 173 */ 174 public void startProduction(ImageConsumer ic) { 175 if (proxies == null) { 176 proxies = new Hashtable<>(); 177 } 178 ImageFilter imgf = (ImageFilter) proxies.get(ic); 179 if (imgf == null) { 180 imgf = filter.getFilterInstance(ic); 181 proxies.put(ic, imgf); 182 } 183 src.startProduction(imgf); 184 } 185 186 /** 187 * Requests that a given ImageConsumer have the image data delivered 188 * one more time in top-down, left-right order. The request is 189 * handed to the ImageFilter for further processing, since the 190 * ability to preserve the pixel ordering depends on the filter. 191 * 192 * <p> 193 * This method is public as a side effect 194 * of this class implementing 195 * the <code>ImageProducer</code> interface. 196 * It should not be called from user code, 197 * and its behavior if called from user code is unspecified. 198 * 199 * @see ImageConsumer 200 */ 201 public void requestTopDownLeftRightResend(ImageConsumer ic) { 202 if (proxies != null) { 203 ImageFilter imgf = (ImageFilter) proxies.get(ic); 204 if (imgf != null) { 205 imgf.resendTopDownLeftRight(src); 206 } 207 } 208 } 209 }