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