001: /*
002: * $RCSfile: PeriodicShiftDescriptor.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:42 $
010: * $State: Exp $
011: */
012: package javax.media.jai.operator;
013:
014: import java.awt.RenderingHints;
015: import java.awt.image.RenderedImage;
016: import java.awt.image.renderable.ParameterBlock;
017: import java.awt.image.renderable.RenderableImage;
018: import javax.media.jai.JAI;
019: import javax.media.jai.OperationDescriptorImpl;
020: import javax.media.jai.ParameterBlockJAI;
021: import javax.media.jai.RenderableOp;
022: import javax.media.jai.RenderedOp;
023: import javax.media.jai.registry.RenderableRegistryMode;
024: import javax.media.jai.registry.RenderedRegistryMode;
025:
026: /**
027: * An <code>OperationDescriptor</code> describing the "PeriodicShift"
028: * operation.
029: *
030: * <p> The destination image of the "PeriodicShift" operation is the
031: * infinite periodic extension of the source image with horizontal and
032: * vertical periods equal to the image width and height, respectively,
033: * shifted by a specified amount along each axis and clipped to the
034: * bounds of the source image. Thus for each band <i>b</i> the destination
035: * image sample at location <i>(x,y)</i> is defined by:
036: *
037: * <pre>
038: * if(x < width - shiftX) {
039: * if(y < height - shiftY) {
040: * dst[x][y][b] = src[x + shiftX][y + shiftY][b];
041: * } else {
042: * dst[x][y][b] = src[x + shiftX][y - height + shiftY][b];
043: * }
044: * } else {
045: * if(y < height - shiftY) {
046: * dst[x][y][b] = src[x - width + shiftX][y + shiftY][b];
047: * } else {
048: * dst[x][y][b] = src[x - width + shiftX][y - height + shiftY][b];
049: * }
050: * }
051: * </pre>
052: *
053: * where <i>shiftX</i> and <code>shiftY</code> denote the translation factors
054: * along the <i>X</i> and <i>Y</i> axes, respectively.
055: *
056: * <p><table border=1>
057: * <caption>Resource List</caption>
058: * <tr><th>Name</th> <th>Value</th></tr>
059: * <tr><td>GlobalName</td> <td>PeriodicShift</td></tr>
060: * <tr><td>LocalName</td> <td>PeriodicShift</td></tr>
061: * <tr><td>Vendor</td> <td>com.sun.media.jai</td></tr>
062: * <tr><td>Description</td> <td>Computes the periodic translation of an image.</td></tr>
063: * <tr><td>DocURL</td> <td>http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/PeriodicShiftDescriptor.html</td></tr>
064: * <tr><td>Version</td> <td>1.0</td></tr>
065: * <tr><td>arg0Desc</td> <td>The displacement in the X direction.</td></tr>
066: * <tr><td>arg1Desc</td> <td>The displacement in the Y direction.</td></tr>
067: * </table></p>
068: *
069: * <p><table border=1>
070: * <caption>Parameter List</caption>
071: * <tr><th>Name</th> <th>Class Type</th>
072: * <th>Default Value</th></tr>
073: * <tr><td>shiftX</td> <td>java.lang.Integer</td>
074: * <td>sourceWidth/2</td>
075: * <tr><td>shiftY</td> <td>java.lang.Integer</td>
076: * <td>sourceHeight/2</td>
077: * </table></p>
078: *
079: * @see javax.media.jai.OperationDescriptor
080: */
081: public class PeriodicShiftDescriptor extends OperationDescriptorImpl {
082:
083: /**
084: * The resource strings that provide the general documentation
085: * and specify the parameter list for this operation.
086: */
087: private static final String[][] resources = {
088: { "GlobalName", "PeriodicShift" },
089: { "LocalName", "PeriodicShift" },
090: { "Vendor", "com.sun.media.jai" },
091: { "Description",
092: JaiI18N.getString("PeriodicShiftDescriptor0") },
093: {
094: "DocURL",
095: "http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/PeriodicShiftDescriptor.html" },
096: { "Version", JaiI18N.getString("DescriptorVersion") },
097: { "arg0Desc", JaiI18N.getString("PeriodicShiftDescriptor1") },
098: { "arg1Desc", JaiI18N.getString("PeriodicShiftDescriptor2") } };
099:
100: /** The parameter class list for this operation. */
101: private static final Class[] paramClasses = {
102: java.lang.Integer.class, java.lang.Integer.class };
103:
104: /** The parameter name list for this operation. */
105: private static final String[] paramNames = { "shiftX", "shiftY" };
106:
107: /** The parameter default value list for this operation. */
108: private static final Object[] paramDefaults = { null, null };
109:
110: private static final String[] supportedModes = { "rendered",
111: "renderable" };
112:
113: /** Constructor. */
114: public PeriodicShiftDescriptor() {
115: super (resources, supportedModes, 1, paramNames, paramClasses,
116: paramDefaults, null);
117: }
118:
119: /**
120: * Validates the input parameters.
121: *
122: * <p> In addition to the standard checks performed by the
123: * superclass method, this method checks that "shiftX" and
124: * "shiftY" are between 0 and the source image width and
125: * height, respectively.
126: */
127: public boolean validateArguments(String modeName,
128: ParameterBlock args, StringBuffer msg) {
129: if (!super .validateArguments(modeName, args, msg)) {
130: return false;
131: }
132:
133: if (!modeName.equalsIgnoreCase("rendered"))
134: return true;
135:
136: RenderedImage src = args.getRenderedSource(0);
137:
138: // Set non-static default values based on source
139: if (args.getObjectParameter(0) == null) {
140: args.set(new Integer(src.getWidth() / 2), 0);
141: }
142: if (args.getObjectParameter(1) == null) {
143: args.set(new Integer(src.getHeight() / 2), 1);
144: }
145:
146: int shiftX = args.getIntParameter(0);
147: int shiftY = args.getIntParameter(1);
148: if (shiftX < 0 || shiftX >= src.getWidth() || shiftY < 0
149: || shiftY >= src.getHeight()) {
150: msg.append(getName() + " "
151: + JaiI18N.getString("PeriodicShiftDescriptor3"));
152: return false;
153: }
154:
155: return true;
156: }
157:
158: /**
159: * Computes the periodic translation of an image.
160: *
161: * <p>Creates a <code>ParameterBlockJAI</code> from all
162: * supplied arguments except <code>hints</code> and invokes
163: * {@link JAI#create(String,ParameterBlock,RenderingHints)}.
164: *
165: * @see JAI
166: * @see ParameterBlockJAI
167: * @see RenderedOp
168: *
169: * @param source0 <code>RenderedImage</code> source 0.
170: * @param shiftX The displacement in the X direction.
171: * May be <code>null</code>.
172: * @param shiftY The displacement in the Y direction.
173: * May be <code>null</code>.
174: * @param hints The <code>RenderingHints</code> to use.
175: * May be <code>null</code>.
176: * @return The <code>RenderedOp</code> destination.
177: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
178: */
179: public static RenderedOp create(RenderedImage source0,
180: Integer shiftX, Integer shiftY, RenderingHints hints) {
181: ParameterBlockJAI pb = new ParameterBlockJAI("PeriodicShift",
182: RenderedRegistryMode.MODE_NAME);
183:
184: pb.setSource("source0", source0);
185:
186: pb.setParameter("shiftX", shiftX);
187: pb.setParameter("shiftY", shiftY);
188:
189: return JAI.create("PeriodicShift", pb, hints);
190: }
191:
192: /**
193: * Computes the periodic translation of an image.
194: *
195: * <p>Creates a <code>ParameterBlockJAI</code> from all
196: * supplied arguments except <code>hints</code> and invokes
197: * {@link JAI#createRenderable(String,ParameterBlock,RenderingHints)}.
198: *
199: * @see JAI
200: * @see ParameterBlockJAI
201: * @see RenderableOp
202: *
203: * @param source0 <code>RenderableImage</code> source 0.
204: * @param shiftX The displacement in the X direction.
205: * May be <code>null</code>.
206: * @param shiftY The displacement in the Y direction.
207: * May be <code>null</code>.
208: * @param hints The <code>RenderingHints</code> to use.
209: * May be <code>null</code>.
210: * @return The <code>RenderableOp</code> destination.
211: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
212: */
213: public static RenderableOp createRenderable(
214: RenderableImage source0, Integer shiftX, Integer shiftY,
215: RenderingHints hints) {
216: ParameterBlockJAI pb = new ParameterBlockJAI("PeriodicShift",
217: RenderableRegistryMode.MODE_NAME);
218:
219: pb.setSource("source0", source0);
220:
221: pb.setParameter("shiftX", shiftX);
222: pb.setParameter("shiftY", shiftY);
223:
224: return JAI.createRenderable("PeriodicShift", pb, hints);
225: }
226: }
|