1 /*
2  * $RCSfile: MagnitudeSquaredDescriptor.java,v $
3  *
4  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
5  *
6  * Use is subject to license terms.
7  *
8  * $Revision: 1.1 $
9  * $Date: 2005/02/11 04:57:38 $
10  * $State: Exp $
11  */
12 package com.lightcrafts.mediax.jai.operator;
13 import java.awt.RenderingHints;
14 import java.awt.image.RenderedImage;
15 import java.awt.image.renderable.ParameterBlock;
16 import java.awt.image.renderable.RenderableImage;
17 import com.lightcrafts.mediax.jai.JAI;
18 import com.lightcrafts.mediax.jai.OperationDescriptorImpl;
19 import com.lightcrafts.mediax.jai.ParameterBlockJAI;
20 import com.lightcrafts.mediax.jai.PropertyGenerator;
21 import com.lightcrafts.mediax.jai.RenderableOp;
22 import com.lightcrafts.mediax.jai.RenderedOp;
23 import com.lightcrafts.mediax.jai.registry.RenderableRegistryMode;
24 import com.lightcrafts.mediax.jai.registry.RenderedRegistryMode;
25 
26 /**
27  * An <code>OperationDescriptor</code> describing the
28  * "MagnitudeSquared" operation.
29  *
30  * <p> The "MagnitudeSquared" operation computes the squared magnitude or
31  * of each pixel of a complex image.  The source image must have an even
32  * number of bands, with the even bands (0, 2, ...) representing the real
33  * parts and the odd bands (1, 3, ...) the imaginary parts of each complex
34  * pixel.  The destination image has at most half the number of bands of the
35  * source image with each sample in a pixel representing the magnitude of the
36  * corresponding complex source sample.  The magnitude squared values of the
37  * destination image are defined for a given sample by the pseudocode:
38  *
39  * <pre>dstPixel[x][y][b] = src[x][y][2*b]^2 + src[x][y][2*b + 1]^2</pre>
40  *
41  * where the number of bands <i>b</i> varies from zero to one less than the
42  * number of bands in the destination image.
43  *
44  * <p> For integral image datatypes, the result will be rounded and clamped
45  * as needed.
46  *
47  * <p>"MagnitudeSquared" defines a PropertyGenerator that sets the "COMPLEX"
48  * property of the image to <code>java.lang.Boolean.FALSE</code>, which may
49  * be retrieved by calling the <code>getProperty()</code> method with
50  * "COMPLEX" as the property name.
51  *
52  * <p><table border=1>
53  * <caption>Resource List</caption>
54  * <tr><th>Name</th>        <th>Value</th></tr>
55  * <tr><td>GlobalName</td>  <td>MagnitudeSquared</td></tr>
56  * <tr><td>LocalName</td>   <td>MagnitudeSquared</td></tr>
57  * <tr><td>Vendor</td>      <td>com.lightcrafts.media.jai</td></tr>
58  * <tr><td>Description</td> <td>Computes the squared magnitude of each
59  *                              pixel of a complex image.</td></tr>
60  * <tr><td>DocURL</td>      <td>http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/MagnitudeSquaredDescriptor.html</td></tr>
61  * <tr><td>Version</td>     <td>1.0</td></tr>
62  * </table></p>
63  *
64  * <p> No parameters are needed for the "MagnitudeSquared" operation.
65  *
66  * @see com.lightcrafts.mediax.jai.OperationDescriptor
67  */
68 public class MagnitudeSquaredDescriptor extends OperationDescriptorImpl {
69 
70     /**
71      * The resource strings that provide the general documentation
72      * and specify the parameter list for this operation.
73      */
74     private static final String[][] resources = {
75         {"GlobalName",  "MagnitudeSquared"},
76         {"LocalName",   "MagnitudeSquared"},
77         {"Vendor",      "com.lightcrafts.media.jai"},
78         {"Description", JaiI18N.getString("MagnitudeSquaredDescriptor0")},
79         {"DocURL",      "http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/MagnitudeSquaredDescriptor.html"},
80         {"Version",     JaiI18N.getString("DescriptorVersion")}
81     };
82 
83     private static final String[] supportedModes = {
84 	"rendered",
85 	"renderable"
86     };
87 
88     /** Constructor. */
MagnitudeSquaredDescriptor()89     public MagnitudeSquaredDescriptor() {
90         super(resources, supportedModes, 1, null, null, null, null);
91     }
92 
93     /**
94      * Returns an array of <code>PropertyGenerators</code> implementing
95      * property inheritance for the "MagnitudeSquared" operation.
96      *
97      * @return  An array of property generators.
98      */
getPropertyGenerators(String modeName)99     public PropertyGenerator[] getPropertyGenerators(String modeName) {
100         PropertyGenerator[] pg = new PropertyGenerator[1];
101         pg[0] = new ComplexPropertyGenerator();
102         return pg;
103     }
104 
105     /**
106      * Validates the input source.
107      *
108      * <p> In addition to the standard checks performed by the
109      * superclass method, this method checks that the source image
110      * has an even number of bands.
111      */
validateSources(String modeName, ParameterBlock args, StringBuffer msg)112     protected boolean validateSources(String modeName,
113 				      ParameterBlock args,
114                                       StringBuffer msg) {
115         if (!super.validateSources(modeName, args, msg)) {
116             return false;
117         }
118 
119 	if (!modeName.equalsIgnoreCase("rendered"))
120 	    return true;
121 
122 	RenderedImage src = args.getRenderedSource(0);
123 
124         int bands = src.getSampleModel().getNumBands();
125 
126         if (bands % 2 != 0) {
127             msg.append(getName() + " " +
128                        JaiI18N.getString("MagnitudeSquaredDescriptor1"));
129             return false;
130         }
131 
132         return true;
133     }
134 
135 
136     /**
137      * Computes the squared magnitude of each pixel of a complex image.
138      *
139      * <p>Creates a <code>ParameterBlockJAI</code> from all
140      * supplied arguments except <code>hints</code> and invokes
141      * {@link JAI#create(String,ParameterBlock,RenderingHints)}.
142      *
143      * @see JAI
144      * @see ParameterBlockJAI
145      * @see RenderedOp
146      *
147      * @param source0 <code>RenderedImage</code> source 0.
148      * @param hints The <code>RenderingHints</code> to use.
149      * May be <code>null</code>.
150      * @return The <code>RenderedOp</code> destination.
151      * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
152      */
create(RenderedImage source0, RenderingHints hints)153     public static RenderedOp create(RenderedImage source0,
154                                     RenderingHints hints)  {
155         ParameterBlockJAI pb =
156             new ParameterBlockJAI("MagnitudeSquared",
157                                   RenderedRegistryMode.MODE_NAME);
158 
159         pb.setSource("source0", source0);
160 
161         return JAI.create("MagnitudeSquared", pb, hints);
162     }
163 
164     /**
165      * Computes the squared magnitude of each pixel of a complex image.
166      *
167      * <p>Creates a <code>ParameterBlockJAI</code> from all
168      * supplied arguments except <code>hints</code> and invokes
169      * {@link JAI#createRenderable(String,ParameterBlock,RenderingHints)}.
170      *
171      * @see JAI
172      * @see ParameterBlockJAI
173      * @see RenderableOp
174      *
175      * @param source0 <code>RenderableImage</code> source 0.
176      * @param hints The <code>RenderingHints</code> to use.
177      * May be <code>null</code>.
178      * @return The <code>RenderableOp</code> destination.
179      * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
180      */
createRenderable(RenderableImage source0, RenderingHints hints)181     public static RenderableOp createRenderable(RenderableImage source0,
182                                                 RenderingHints hints)  {
183         ParameterBlockJAI pb =
184             new ParameterBlockJAI("MagnitudeSquared",
185                                   RenderableRegistryMode.MODE_NAME);
186 
187         pb.setSource("source0", source0);
188 
189         return JAI.createRenderable("MagnitudeSquared", pb, hints);
190     }
191 }
192