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