001: /*
002: * $RCSfile: DivideComplexDescriptor.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:34 $
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.PropertyGenerator;
022: import javax.media.jai.RenderableOp;
023: import javax.media.jai.RenderedOp;
024: import javax.media.jai.registry.RenderableRegistryMode;
025: import javax.media.jai.registry.RenderedRegistryMode;
026:
027: /**
028: * An <code>OperationDescriptor</code> describing the "DivideComplex"
029: * operation.
030: *
031: * <p> The "DivideComplex" operation divides two images representing
032: * complex data. The source images must each contain an even number of bands
033: * with the even-indexed bands (0, 2, ...) representing the real and the
034: * odd-indexed bands (1, 3, ...) the imaginary parts of each pixel. The
035: * destination image similarly contains an even number of bands with the
036: * same interpretation and with contents defined by:
037: *
038: * <pre>
039: * a = src0[x][y][2*k];
040: * b = src0[x][y][2*k+1];
041: * c = src1[x][y][2*k];
042: * d = src1[x][y][2*k+1];
043: *
044: * dst[x][y][2*k] = (a*c + b*d)/(c^2 + d^2)
045: * dst[x][y][2*k+1] = (b*c - a*d)/(c^2 + d^2)
046: * </pre>
047: *
048: * where 0 <= <i>k</i> < numBands/2.
049: *
050: * By default, the number of bands of the destination image is the
051: * the minimum of the number of bands of the two sources, and the
052: * data type is the biggest data type of the sources.
053: * However, the number of destination bands can be specified to be
054: * M = 2*L through an <code>ImageLayout</code> hint, when
055: * one source image has 2 bands and the other has N = 2*K bands
056: * where K > 1, with a natural restriction 1 <= L <= K.
057: * In such a special case,
058: * if the first source has 2 bands its single complex component
059: * will be divided by each of the first L complex components of the second
060: * source; if the second source has 2 bands its single complex component will
061: * divide each of the L complex components of the first source.
062: *
063: * <p> If the result of the operation underflows/overflows the
064: * minimum/maximum value supported by the destination data type, then it will
065: * be clamped to the minimum/maximum value respectively.
066: *
067: * <p>"DivideComplex" defines a PropertyGenerator that sets the "COMPLEX"
068: * property of the image to <code>java.lang.Boolean.TRUE</code>, which may
069: * be retrieved by calling the <code>getProperty()</code> method with
070: * "COMPLEX" as the property name.
071: *
072: * <p><table border=1>
073: * <caption>Resource List</caption>
074: * <tr><th>Name</th> <th>Value</th></tr>
075: * <tr><td>GlobalName</td> <td>DivideComplex</td></tr>
076: * <tr><td>LocalName</td> <td>DivideComplex</td></tr>
077: * <tr><td>Vendor</td> <td>com.sun.media.jai</td></tr>
078: * <tr><td>Description</td> <td>Compute the complex quotient of two images.</td></tr>
079: * <tr><td>DocURL</td> <td>http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/DivideComplexDescriptor.html</td></tr>
080: * <tr><td>Version</td> <td>1.0</td></tr>
081: * </table></p>
082: *
083: * <p> No parameters are needed for the "DivideComplex" operation.
084: *
085: * @see javax.media.jai.OperationDescriptor
086: */
087: public class DivideComplexDescriptor extends OperationDescriptorImpl {
088:
089: /**
090: * The resource strings that provide the general documentation
091: * and specify the parameter list for this operation.
092: */
093: private static final String[][] resources = {
094: { "GlobalName", "DivideComplex" },
095: { "LocalName", "DivideComplex" },
096: { "Vendor", "com.sun.media.jai" },
097: { "Description",
098: JaiI18N.getString("DivideComplexDescriptor0") },
099: {
100: "DocURL",
101: "http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/DivideComplexDescriptor.html" },
102: { "Version", JaiI18N.getString("DescriptorVersion") } };
103:
104: private static final String[] supportedModes = { "rendered",
105: "renderable" };
106:
107: /** Constructor. */
108: public DivideComplexDescriptor() {
109: super (resources, supportedModes, 2, null, null, null, null);
110: }
111:
112: /**
113: * Validates the input sources.
114: *
115: * <p> In addition to the standard checks performed by the
116: * superclass method, this method checks that both sources have
117: * an even number of bands.
118: */
119: protected boolean validateSources(String modeName,
120: ParameterBlock args, StringBuffer msg) {
121: if (!super .validateSources(modeName, args, msg)) {
122: return false;
123: }
124:
125: if (!modeName.equalsIgnoreCase("rendered"))
126: return true;
127:
128: RenderedImage src1 = args.getRenderedSource(0);
129: RenderedImage src2 = args.getRenderedSource(1);
130:
131: if (src1.getSampleModel().getNumBands() % 2 != 0
132: || src2.getSampleModel().getNumBands() % 2 != 0) {
133: msg.append(getName() + " "
134: + JaiI18N.getString("DivideComplexDescriptor1"));
135: return false;
136: }
137:
138: return true;
139: }
140:
141: /**
142: * Returns an array of <code>PropertyGenerators</code> implementing
143: * property inheritance for the "DivideComplex" operation.
144: *
145: * @return An array of property generators.
146: */
147: public PropertyGenerator[] getPropertyGenerators(String modeName) {
148: PropertyGenerator[] pg = new PropertyGenerator[1];
149: pg[0] = new ComplexPropertyGenerator();
150: return pg;
151: }
152:
153: /**
154: * Compute the complex quotient of two images.
155: *
156: * <p>Creates a <code>ParameterBlockJAI</code> from all
157: * supplied arguments except <code>hints</code> and invokes
158: * {@link JAI#create(String,ParameterBlock,RenderingHints)}.
159: *
160: * @see JAI
161: * @see ParameterBlockJAI
162: * @see RenderedOp
163: *
164: * @param source0 <code>RenderedImage</code> source 0.
165: * @param source1 <code>RenderedImage</code> source 1.
166: * @param hints The <code>RenderingHints</code> to use.
167: * May be <code>null</code>.
168: * @return The <code>RenderedOp</code> destination.
169: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
170: * @throws IllegalArgumentException if <code>source1</code> is <code>null</code>.
171: */
172: public static RenderedOp create(RenderedImage source0,
173: RenderedImage source1, RenderingHints hints) {
174: ParameterBlockJAI pb = new ParameterBlockJAI("DivideComplex",
175: RenderedRegistryMode.MODE_NAME);
176:
177: pb.setSource("source0", source0);
178: pb.setSource("source1", source1);
179:
180: return JAI.create("DivideComplex", pb, hints);
181: }
182:
183: /**
184: * Compute the complex quotient of two images.
185: *
186: * <p>Creates a <code>ParameterBlockJAI</code> from all
187: * supplied arguments except <code>hints</code> and invokes
188: * {@link JAI#createRenderable(String,ParameterBlock,RenderingHints)}.
189: *
190: * @see JAI
191: * @see ParameterBlockJAI
192: * @see RenderableOp
193: *
194: * @param source0 <code>RenderableImage</code> source 0.
195: * @param source1 <code>RenderableImage</code> source 1.
196: * @param hints The <code>RenderingHints</code> to use.
197: * May be <code>null</code>.
198: * @return The <code>RenderableOp</code> destination.
199: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
200: * @throws IllegalArgumentException if <code>source1</code> is <code>null</code>.
201: */
202: public static RenderableOp createRenderable(
203: RenderableImage source0, RenderableImage source1,
204: RenderingHints hints) {
205: ParameterBlockJAI pb = new ParameterBlockJAI("DivideComplex",
206: RenderableRegistryMode.MODE_NAME);
207:
208: pb.setSource("source0", source0);
209: pb.setSource("source1", source1);
210:
211: return JAI.createRenderable("DivideComplex", pb, hints);
212: }
213: }
|