001: /*
002: * $RCSfile: IDFTDescriptor.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:37 $
010: * $State: Exp $
011: */
012: package javax.media.jai.operator;
013:
014: import com.sun.media.jai.util.PropertyGeneratorImpl;
015: import java.awt.RenderingHints;
016: import java.awt.image.RenderedImage;
017: import java.awt.image.renderable.ParameterBlock;
018: import java.awt.image.renderable.RenderableImage;
019: import javax.media.jai.EnumeratedParameter;
020: import javax.media.jai.JAI;
021: import javax.media.jai.OperationDescriptorImpl;
022: import javax.media.jai.ParameterBlockJAI;
023: import javax.media.jai.PropertyGenerator;
024: import javax.media.jai.RenderableOp;
025: import javax.media.jai.RenderedOp;
026: import javax.media.jai.operator.DFTDataNature;
027: import javax.media.jai.operator.DFTScalingType;
028: import javax.media.jai.registry.RenderableRegistryMode;
029: import javax.media.jai.registry.RenderedRegistryMode;
030:
031: /**
032: * This property generator computes the properties for the operation
033: * "IDFT" dynamically.
034: */
035: class IDFTPropertyGenerator extends PropertyGeneratorImpl {
036:
037: /** Constructor. */
038: public IDFTPropertyGenerator() {
039: super (new String[] { "COMPLEX" },
040: new Class[] { Boolean.class }, new Class[] {
041: RenderedOp.class, RenderableOp.class });
042: }
043:
044: /**
045: * Returns the specified property.
046: *
047: * @param name Property name.
048: * @param opNode Operation node.
049: */
050: public Object getProperty(String name, Object opNode) {
051: validate(name, opNode);
052:
053: if (name.equalsIgnoreCase("complex")) {
054: if (opNode instanceof RenderedOp) {
055: RenderedOp op = (RenderedOp) opNode;
056: ParameterBlock pb = op.getParameterBlock();
057: DFTDataNature dataNature = (DFTDataNature) pb
058: .getObjectParameter(1);
059: return dataNature
060: .equals(IDFTDescriptor.COMPLEX_TO_REAL) ? Boolean.FALSE
061: : Boolean.TRUE;
062: } else if (opNode instanceof RenderableOp) {
063: RenderableOp op = (RenderableOp) opNode;
064: ParameterBlock pb = op.getParameterBlock();
065: DFTDataNature dataNature = (DFTDataNature) pb
066: .getObjectParameter(1);
067: return dataNature
068: .equals(IDFTDescriptor.COMPLEX_TO_REAL) ? Boolean.FALSE
069: : Boolean.TRUE;
070: }
071: }
072:
073: return java.awt.Image.UndefinedProperty;
074: }
075: }
076:
077: /**
078: * An <code>OperationDescriptor</code> describing the "IDFT" operation.
079: *
080: * <p> The "IDFT" operation computes the inverse discrete Fourier transform of
081: * an image. A positive exponential is used as the basis function for the
082: * transform. The operation supports real-to-complex, complex-to-complex, and
083: * complex-to-real transforms. A complex image must have an even number of
084: * bands, with the even bands (0, 2, ...) representing the real parts and the
085: * odd bands (1, 3, ...) the imaginary parts of each complex pixel.
086: *
087: * <p> The nature of the source and destination data is specified by the
088: * "dataNature" operation parameter. If the source data are complex then
089: * the number of bands in the source image must be a multiple of 2. The
090: * number of bands in the destination must match that which would be expected
091: * given the number of bands in the source image and the specified nature
092: * of the source and destination data. If the source image is real then the
093: * number of bands in the destination will be twice that in the source. If
094: * the destination image is real than the number of bands in the destination
095: * will be half that in the source. Otherwise the number of bands in the
096: * source and destination must be equal.
097: *
098: * <p> If an underlying fast Fourier transform (FFT) implementation is used
099: * which requires that the image dimensions be powers of 2, then the width
100: * and height may each be increased to the power of 2 greater than or equal
101: * to the original width and height, respectively.
102: *
103: * <p>"IDFT" defines a PropertyGenerator that sets the "COMPLEX" property of
104: * the image to <code>java.lang.Boolean.FALSE</code> if the "dataNature"
105: * operation parameter is equal to IDFTDescriptor.COMPLEX_TO_REAL and to
106: * <code>java.lang.Boolean.TRUE</code> otherwise. The value of this property
107: * may be retrieved by calling the <code>getProperty()</code> method with
108: * "COMPLEX" as the property name.
109: *
110: * <p><table border=1>
111: * <caption>Resource List</caption>
112: * <tr><th>Name</th> <th>Value</th></tr>
113: * <tr><td>GlobalName</td> <td>IDFT</td></tr>
114: * <tr><td>LocalName</td> <td>IDFT</td></tr>
115: * <tr><td>Vendor</td> <td>com.sun.media.jai</td></tr>
116: * <tr><td>Description</td> <td>Computes the discrete Fourier transform of
117: * an image.</td></tr>
118: * <tr><td>DocURL</td> <td>http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/IDFTDescriptor.html</td></tr>
119: * <tr><td>Version</td> <td>1.0</td></tr>
120: * <tr><td>arg0Desc</td> <td>The type of scaling to be used.</td></tr>
121: * <tr><td>arg1Desc</td> <td>The nature of the data.</td></tr>
122: * </table></p>
123: *
124: * <p><table border=1>
125: * <caption>Parameter List</caption>
126: * <tr><th>Name</th> <th>Class Type</th>
127: * <th>Default Value</th></tr>
128: * <tr><td>scalingType</td> <td>javax.media.jai.operator.DFTScalingType</td>
129: * <td>IDFTDescriptor.SCALING_DIMENSIONS</td>
130: * <tr><td>dataNature</td> <td>javax.media.jai.operator.DFTDataNature</td>
131: * <td>IDFTDescriptor.COMPLEX_TO_REAL</td>
132: * </table></p>
133: *
134: * @see javax.media.jai.OperationDescriptor
135: * @see DFTDescriptor
136: * @see DFTDataNature
137: * @see DFTScalingType
138: */
139: public class IDFTDescriptor extends OperationDescriptorImpl {
140: /**
141: * A flag indicating that the transform is not to be scaled.
142: */
143: public static final DFTScalingType SCALING_NONE = DFTDescriptor.SCALING_NONE;
144:
145: /**
146: * A flag indicating that the transform is to be scaled by the square
147: * root of the product of its dimensions.
148: */
149: public static final DFTScalingType SCALING_UNITARY = DFTDescriptor.SCALING_UNITARY;
150:
151: /**
152: * A flag indicating that the transform is to be scaled by the product
153: * of its dimensions.
154: */
155: public static final DFTScalingType SCALING_DIMENSIONS = DFTDescriptor.SCALING_DIMENSIONS;
156:
157: /**
158: * A flag indicating that the source data are real and the destination
159: * data complex.
160: */
161: public static final DFTDataNature REAL_TO_COMPLEX = DFTDescriptor.REAL_TO_COMPLEX;
162:
163: /**
164: * A flag indicating that the source and destination data are both complex.
165: */
166: public static final DFTDataNature COMPLEX_TO_COMPLEX = DFTDescriptor.COMPLEX_TO_COMPLEX;
167:
168: /**
169: * A flag indicating that the source data are complex and the destination
170: * data real.
171: */
172: public static final DFTDataNature COMPLEX_TO_REAL = DFTDescriptor.COMPLEX_TO_REAL;
173:
174: /**
175: * The resource strings that provide the general documentation
176: * and specify the parameter list for this operation.
177: */
178: private static final String[][] resources = {
179: { "GlobalName", "IDFT" },
180: { "LocalName", "IDFT" },
181: { "Vendor", "com.sun.media.jai" },
182: { "Description", JaiI18N.getString("IDFTDescriptor0") },
183: {
184: "DocURL",
185: "http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/IDFTDescriptor.html" },
186: { "Version", JaiI18N.getString("DescriptorVersion2") },
187: { "arg0Desc", JaiI18N.getString("IDFTDescriptor1") },
188: { "arg1Desc", JaiI18N.getString("IDFTDescriptor2") } };
189:
190: /** The parameter class list for this operation. */
191: private static final Class[] paramClasses = { DFTScalingType.class,
192: DFTDataNature.class };
193:
194: /** The parameter name list for this operation. */
195: private static final String[] paramNames = { "scalingType",
196: "dataNature" };
197:
198: /** The parameter default value list for this operation. */
199: private static final Object[] paramDefaults = {
200: IDFTDescriptor.SCALING_DIMENSIONS,
201: IDFTDescriptor.COMPLEX_TO_REAL };
202:
203: private static final String[] supportedModes = { "rendered",
204: "renderable" };
205:
206: /** Constructor. */
207: public IDFTDescriptor() {
208: super (resources, supportedModes, 1, paramNames, paramClasses,
209: paramDefaults, null);
210: }
211:
212: /**
213: * Validates the input source and parameters.
214: *
215: * <p> In addition to the standard checks performed by the
216: * superclass method, this method checks that "scalingType" is one
217: * of <code>SCALING_NONE</code>, <code>SCALING_UNITARY</code>, or
218: * <code>SCALING_DIMENSIONS</code>, and that "dataNature" is one
219: * of <code>REAL_TO_COMPLEX</code>,
220: * <code>COMPLEX_TO_COMPLEX</code>, or
221: * <code>COMPLEX_TO_REAL</code>. Also, if "dataNature" is
222: * <code>COMPLEX_TO_COMPLEX</code> or <code>COMPLEX_TO_REAL</code>
223: * the number of source bands must be even.
224: */
225: public boolean validateArguments(String modeName,
226: ParameterBlock args, StringBuffer msg) {
227: if (!super .validateArguments(modeName, args, msg)) {
228: return false;
229: }
230:
231: if (!modeName.equalsIgnoreCase("rendered"))
232: return true;
233:
234: // Check source band count: must be even for a complex source.
235: EnumeratedParameter dataNature = (EnumeratedParameter) args
236: .getObjectParameter(1);
237:
238: if (!dataNature.equals(IDFTDescriptor.REAL_TO_COMPLEX)) {
239: RenderedImage src = args.getRenderedSource(0);
240:
241: if (src.getSampleModel().getNumBands() % 2 != 0) {
242: msg.append(getName() + " "
243: + JaiI18N.getString("IDFTDescriptor5"));
244: return false;
245: }
246: }
247:
248: return true;
249: }
250:
251: /**
252: * Returns an array of <code>PropertyGenerators</code> implementing
253: * property inheritance for the "IDFT" operation.
254: *
255: * @return An array of property generators.
256: */
257: public PropertyGenerator[] getPropertyGenerators(String modeName) {
258: PropertyGenerator[] pg = new PropertyGenerator[1];
259: pg[0] = new IDFTPropertyGenerator();
260: return pg;
261: }
262:
263: /**
264: * Computes the inverse discrete Fourier transform of an image.
265: *
266: * <p>Creates a <code>ParameterBlockJAI</code> from all
267: * supplied arguments except <code>hints</code> and invokes
268: * {@link JAI#create(String,ParameterBlock,RenderingHints)}.
269: *
270: * @see JAI
271: * @see ParameterBlockJAI
272: * @see RenderedOp
273: *
274: * @param source0 <code>RenderedImage</code> source 0.
275: * @param scalingType The type of scaling to perform.
276: * May be <code>null</code>.
277: * @param dataNature The nature of the data.
278: * May be <code>null</code>.
279: * @param hints The <code>RenderingHints</code> to use.
280: * May be <code>null</code>.
281: * @return The <code>RenderedOp</code> destination.
282: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
283: */
284: public static RenderedOp create(RenderedImage source0,
285: DFTScalingType scalingType, DFTDataNature dataNature,
286: RenderingHints hints) {
287: ParameterBlockJAI pb = new ParameterBlockJAI("IDFT",
288: RenderedRegistryMode.MODE_NAME);
289:
290: pb.setSource("source0", source0);
291:
292: pb.setParameter("scalingType", scalingType);
293: pb.setParameter("dataNature", dataNature);
294:
295: return JAI.create("IDFT", pb, hints);
296: }
297:
298: /**
299: * Computes the inverse discrete Fourier transform of an image.
300: *
301: * <p>Creates a <code>ParameterBlockJAI</code> from all
302: * supplied arguments except <code>hints</code> and invokes
303: * {@link JAI#createRenderable(String,ParameterBlock,RenderingHints)}.
304: *
305: * @see JAI
306: * @see ParameterBlockJAI
307: * @see RenderableOp
308: *
309: * @param source0 <code>RenderableImage</code> source 0.
310: * @param scalingType The type of scaling to perform.
311: * May be <code>null</code>.
312: * @param dataNature The nature of the data.
313: * May be <code>null</code>.
314: * @param hints The <code>RenderingHints</code> to use.
315: * May be <code>null</code>.
316: * @return The <code>RenderableOp</code> destination.
317: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
318: */
319: public static RenderableOp createRenderable(
320: RenderableImage source0, DFTScalingType scalingType,
321: DFTDataNature dataNature, RenderingHints hints) {
322: ParameterBlockJAI pb = new ParameterBlockJAI("IDFT",
323: RenderableRegistryMode.MODE_NAME);
324:
325: pb.setSource("source0", source0);
326:
327: pb.setParameter("scalingType", scalingType);
328: pb.setParameter("dataNature", dataNature);
329:
330: return JAI.createRenderable("IDFT", pb, hints);
331: }
332: }
|