1. /*
  2. * @(#)ReplicateScaleFilter.java 1.16 03/01/23
  3. *
  4. * Copyright 2003 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.ImageConsumer;
  9. import java.awt.image.ColorModel;
  10. import java.util.Hashtable;
  11. import java.awt.Rectangle;
  12. /**
  13. * An ImageFilter class for scaling images using the simplest algorithm.
  14. * This class extends the basic ImageFilter Class to scale an existing
  15. * image and provide a source for a new image containing the resampled
  16. * image. The pixels in the source image are sampled to produce pixels
  17. * for an image of the specified size by replicating rows and columns of
  18. * pixels to scale up or omitting rows and columns of pixels to scale
  19. * down.
  20. * <p>It is meant to be used in conjunction with a FilteredImageSource
  21. * object to produce scaled versions of existing images. Due to
  22. * implementation dependencies, there may be differences in pixel values
  23. * of an image filtered on different platforms.
  24. *
  25. * @see FilteredImageSource
  26. * @see ImageFilter
  27. *
  28. * @version 1.16 01/23/03
  29. * @author Jim Graham
  30. */
  31. public class ReplicateScaleFilter extends ImageFilter {
  32. /**
  33. * The width of the source image.
  34. */
  35. protected int srcWidth;
  36. /**
  37. * The height of the source image.
  38. */
  39. protected int srcHeight;
  40. /**
  41. * The target width to scale the image.
  42. */
  43. protected int destWidth;
  44. /**
  45. * The target height to scale the image.
  46. */
  47. protected int destHeight;
  48. /**
  49. * An <code>int</code> array containing information about a
  50. * row of pixels.
  51. */
  52. protected int srcrows[];
  53. /**
  54. * An <code>int</code> array containing information about a
  55. * column of pixels.
  56. */
  57. protected int srccols[];
  58. /**
  59. * A <code>byte</code> array initialized with a size of
  60. * {@link #destWidth} and used to deliver a row of pixel
  61. * data to the {@link ImageConsumer}.
  62. */
  63. protected Object outpixbuf;
  64. /**
  65. * Constructs a ReplicateScaleFilter that scales the pixels from
  66. * its source Image as specified by the width and height parameters.
  67. * @param width the target width to scale the image
  68. * @param height the target height to scale the image
  69. * @throws IllegalArgumentException if <code>width</code> equals
  70. * zero or <code>height</code> equals zero
  71. */
  72. public ReplicateScaleFilter(int width, int height) {
  73. if (width == 0 || height == 0) {
  74. throw new IllegalArgumentException("Width ("+width+
  75. ") and height ("+height+
  76. ") must be non-zero");
  77. }
  78. destWidth = width;
  79. destHeight = height;
  80. }
  81. /**
  82. * Passes along the properties from the source object after adding a
  83. * property indicating the scale applied.
  84. * <p>
  85. * Note: This method is intended to be called by the
  86. * <code>ImageProducer</code> of the <code>Image</code> whose pixels
  87. * are being filtered. Developers using
  88. * this class to filter pixels from an image should avoid calling
  89. * this method directly since that operation could interfere
  90. * with the filtering operation.
  91. */
  92. public void setProperties(Hashtable props) {
  93. props = (Hashtable) props.clone();
  94. String key = "rescale";
  95. String val = destWidth + "x" + destHeight;
  96. Object o = props.get(key);
  97. if (o != null && o instanceof String) {
  98. val = ((String) o) + ", " + val;
  99. }
  100. props.put(key, val);
  101. super.setProperties(props);
  102. }
  103. /**
  104. * Override the dimensions of the source image and pass the dimensions
  105. * of the new scaled size to the ImageConsumer.
  106. * <p>
  107. * Note: This method is intended to be called by the
  108. * <code>ImageProducer</code> of the <code>Image</code> whose pixels
  109. * are being filtered. Developers using
  110. * this class to filter pixels from an image should avoid calling
  111. * this method directly since that operation could interfere
  112. * with the filtering operation.
  113. * @see ImageConsumer
  114. */
  115. public void setDimensions(int w, int h) {
  116. srcWidth = w;
  117. srcHeight = h;
  118. if (destWidth < 0) {
  119. if (destHeight < 0) {
  120. destWidth = srcWidth;
  121. destHeight = srcHeight;
  122. } else {
  123. destWidth = srcWidth * destHeight / srcHeight;
  124. }
  125. } else if (destHeight < 0) {
  126. destHeight = srcHeight * destWidth / srcWidth;
  127. }
  128. consumer.setDimensions(destWidth, destHeight);
  129. }
  130. private void calculateMaps() {
  131. srcrows = new int[destHeight + 1];
  132. for (int y = 0; y <= destHeight; y++) {
  133. srcrows[y] = (2 * y * srcHeight + srcHeight) / (2 * destHeight);
  134. }
  135. srccols = new int[destWidth + 1];
  136. for (int x = 0; x <= destWidth; x++) {
  137. srccols[x] = (2 * x * srcWidth + srcWidth) / (2 * destWidth);
  138. }
  139. }
  140. /**
  141. * Choose which rows and columns of the delivered byte pixels are
  142. * needed for the destination scaled image and pass through just
  143. * those rows and columns that are needed, replicated as necessary.
  144. * <p>
  145. * Note: This method is intended to be called by the
  146. * <code>ImageProducer</code> of the <code>Image</code> whose pixels
  147. * are being filtered. Developers using
  148. * this class to filter pixels from an image should avoid calling
  149. * this method directly since that operation could interfere
  150. * with the filtering operation.
  151. */
  152. public void setPixels(int x, int y, int w, int h,
  153. ColorModel model, byte pixels[], int off,
  154. int scansize) {
  155. if (srcrows == null || srccols == null) {
  156. calculateMaps();
  157. }
  158. int sx, sy;
  159. int dx1 = (2 * x * destWidth + srcWidth - 1) / (2 * srcWidth);
  160. int dy1 = (2 * y * destHeight + srcHeight - 1) / (2 * srcHeight);
  161. byte outpix[];
  162. if (outpixbuf != null && outpixbuf instanceof byte[]) {
  163. outpix = (byte[]) outpixbuf;
  164. } else {
  165. outpix = new byte[destWidth];
  166. outpixbuf = outpix;
  167. }
  168. for (int dy = dy1; (sy = srcrows[dy]) < y + h; dy++) {
  169. int srcoff = off + scansize * (sy - y);
  170. int dx;
  171. for (dx = dx1; (sx = srccols[dx]) < x + w; dx++) {
  172. outpix[dx] = pixels[srcoff + sx - x];
  173. }
  174. if (dx > dx1) {
  175. consumer.setPixels(dx1, dy, dx - dx1, 1,
  176. model, outpix, dx1, destWidth);
  177. }
  178. }
  179. }
  180. /**
  181. * Choose which rows and columns of the delivered int pixels are
  182. * needed for the destination scaled image and pass through just
  183. * those rows and columns that are needed, replicated as necessary.
  184. * <p>
  185. * Note: This method is intended to be called by the
  186. * <code>ImageProducer</code> of the <code>Image</code> whose pixels
  187. * 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. */
  192. public void setPixels(int x, int y, int w, int h,
  193. ColorModel model, int pixels[], int off,
  194. int scansize) {
  195. if (srcrows == null || srccols == null) {
  196. calculateMaps();
  197. }
  198. int sx, sy;
  199. int dx1 = (2 * x * destWidth + srcWidth - 1) / (2 * srcWidth);
  200. int dy1 = (2 * y * destHeight + srcHeight - 1) / (2 * srcHeight);
  201. int outpix[];
  202. if (outpixbuf != null && outpixbuf instanceof int[]) {
  203. outpix = (int[]) outpixbuf;
  204. } else {
  205. outpix = new int[destWidth];
  206. outpixbuf = outpix;
  207. }
  208. for (int dy = dy1; (sy = srcrows[dy]) < y + h; dy++) {
  209. int srcoff = off + scansize * (sy - y);
  210. int dx;
  211. for (dx = dx1; (sx = srccols[dx]) < x + w; dx++) {
  212. outpix[dx] = pixels[srcoff + sx - x];
  213. }
  214. if (dx > dx1) {
  215. consumer.setPixels(dx1, dy, dx - dx1, 1,
  216. model, outpix, dx1, destWidth);
  217. }
  218. }
  219. }
  220. }