001: /*
002: * $RCSfile: BorderExtender.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:57:04 $
010: * $State: Exp $
011: */
012: package javax.media.jai;
013:
014: import java.io.Serializable;
015: import java.awt.Rectangle;
016: import java.awt.image.WritableRaster;
017:
018: /**
019: * An abstract superclass for classes that extend or "pad" a
020: * <code>WritableRaster</code> with additional pixel data taken from a
021: * <code>PlanarImage</code>. Instances of <code>BorderExtender</code>
022: * are used by the <code>getExtendedData()</code> and
023: * <code>copyExtendedData()</code> methods in
024: * <code>PlanarImage</code>.
025: *
026: * <p> Each instance of <code>BorderExtender</code> has an
027: * <code>extend()</code> method that takes a
028: * <code>WritableRaster</code> and a <code>PlanarImage</code>. The
029: * portion of the raster that intersects the bounds of the image will
030: * already contain a copy of the image data. The remaining area is to
031: * be filled in according to the policy of the
032: * <code>BorderExtender</code> subclass.
033: *
034: * <p> The standard subclasses of <code>BorderExtender</code> are
035: * <code>BorderExtenderZero</code>, which fills pixels with zeros;
036: * <code>BorderExtenderConstant</code>, which fills pixels with a
037: * given constant value; <code>BorderExtenderCopy</code>, which copies
038: * the edge pixels of the image; <code>BorderExtenderWrap</code>,
039: * which tiles the plane with repeating copies of the image; and
040: * <code>BorderExtenderReflect</code>, which is like
041: * <code>BorderExtenderWrap</code> except that each copy of the image
042: * is suitably reflected.
043: *
044: * <p> Instances of <code>BorderExtenderConstant</code> are
045: * constructed in the usual way. Instances of the other standard subclasses
046: * are obtained by means of the <code>createInstance()</code> method
047: * of this class.
048: *
049: * <p> <code>BorderExtenderCopy</code> is particularly useful as a way
050: * of padding image data prior to performing area or geometric
051: * operations such as convolution, scaling, and rotation.
052: *
053: * @see PlanarImage#getExtendedData
054: * @see PlanarImage#copyExtendedData
055: * @see BorderExtenderConstant
056: * @see BorderExtenderCopy
057: * @see BorderExtenderReflect
058: * @see BorderExtenderWrap
059: * @see BorderExtenderZero
060: */
061: public abstract class BorderExtender implements Serializable {
062:
063: /** A constant for use in the <code>createInstance</code> method. */
064: public static final int BORDER_ZERO = 0;
065:
066: /** A constant for use in the <code>createInstance</code> method. */
067: public static final int BORDER_COPY = 1;
068:
069: /** A constant for use in the <code>createInstance</code> method. */
070: public static final int BORDER_REFLECT = 2;
071:
072: /** A constant for use in the <code>createInstance</code> method. */
073: public static final int BORDER_WRAP = 3;
074:
075: /** Lazily-constructed singleton BorderExtenderZero. */
076: private static BorderExtender borderExtenderZero = null;
077:
078: /** Lazily-constructed singleton BorderExtenderCopy. */
079: private static BorderExtender borderExtenderCopy = null;
080:
081: /** Lazily-constructed singleton BorderExtenderReflect. */
082: private static BorderExtender borderExtenderReflect = null;
083:
084: /** Lazily-constructed singleton BorderExtenderWrap. */
085: private static BorderExtender borderExtenderWrap = null;
086:
087: /**
088: * Fills in the portions of a given <code>WritableRaster</code> that
089: * lie outside the bounds of a given <code>PlanarImage</code>.
090: * Depending on the policy of the <code>BorderExtender</code>, data
091: * might or might not be derived from the <code>PlanarImage</code>.
092: *
093: * <p> The portion of <code>raster</code> that lies within
094: * <code>im.getBounds()</code> must not be altered. The pixels
095: * within this region should not be assumed to have any particular
096: * values.
097: *
098: * <p> Each subclass may implement a different policy regarding
099: * how the extension data is computed.
100: *
101: * @param raster The <code>WritableRaster</code> the border area of
102: * which is to be filled according to the policy of the
103: * <code>BorderExtender</code>.
104: * @param im The <code>PlanarImage</code> which may provide the
105: * data with which to fill the border area of the
106: * <code>WritableRaster</code>.
107: *
108: * @throws <code>IllegalArgumentException</code> if either parameter is
109: * <code>null</code>.
110: */
111: public abstract void extend(WritableRaster raster, PlanarImage im);
112:
113: /**
114: * Returns an instance of <code>BorderExtender</code> that
115: * implements a given extension policy. The policies understood
116: * by this method are:
117: *
118: * <p> <code>BORDER_ZERO</code>: set sample values to zero.
119: *
120: * <p> <code>BORDER_COPY</code>: set sample values to copies of
121: * the nearest valid pixel. For example, pixels to the left of
122: * the valid rectangle will take on the value of the valid edge
123: * pixel in the same row. Pixels both above and to the left of
124: * the valid rectangle will take on the value of the upper-left
125: * pixel.
126: *
127: * <p> <code>BORDER_REFLECT</code>: the output image is defined
128: * as if mirrors were placed along the edges of the source image.
129: * Thus if the left edge of the valid rectangle lies at X = 10,
130: * pixel (9, Y) will be a copy of pixel (10, Y); pixel (6, Y)
131: * will be a copy of pixel (13, Y).
132: *
133: * <p> <code>BORDER_WRAP</code>: the source image is tiled repeatedly
134: * in the plane.
135: *
136: * <p> Note that this method may not be used to create an instance
137: * of <code>BorderExtenderConstant</code>.
138: *
139: * <p> Any other input value will cause an
140: * <code>IllegalArgumentException</code> to be thrown.
141: *
142: * @param extenderType The type of <code>BorderExtender</code> to create.
143: * Must be one of the predefined class constants
144: * <code>BORDER_COPY</code>,
145: * <code>BORDER_REFLECT</code>,
146: * <code>BORDER_WRAP</code>, or
147: * <code>BORDER_ZERO</code>.
148: *
149: * @throws <code>IllegalArgumentException</code> if the supplied
150: * parameter is not one of the supported predefined constants.
151: */
152: public static BorderExtender createInstance(int extenderType) {
153: switch (extenderType) {
154: case BORDER_ZERO:
155: if (borderExtenderZero == null) {
156: borderExtenderZero = new BorderExtenderZero();
157: }
158: return borderExtenderZero;
159:
160: case BORDER_COPY:
161: if (borderExtenderCopy == null) {
162: borderExtenderCopy = new BorderExtenderCopy();
163: }
164: return borderExtenderCopy;
165:
166: case BORDER_REFLECT:
167: if (borderExtenderReflect == null) {
168: borderExtenderReflect = new BorderExtenderReflect();
169: }
170: return borderExtenderReflect;
171:
172: case BORDER_WRAP:
173: if (borderExtenderWrap == null) {
174: borderExtenderWrap = new BorderExtenderWrap();
175: }
176: return borderExtenderWrap;
177:
178: default:
179: throw new IllegalArgumentException(JaiI18N
180: .getString("BorderExtender0"));
181: }
182: }
183: }
|