1 /*
2  * $RCSfile: ImageFunctionDescriptor.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:37 $
10  * $State: Exp $
11  */
12 package com.lightcrafts.mediax.jai.operator;
13 import com.lightcrafts.media.jai.util.PropertyGeneratorImpl;
14 import java.awt.RenderingHints;
15 import java.awt.image.renderable.ParameterBlock;
16 import com.lightcrafts.mediax.jai.ImageFunction;
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.RenderedRegistryMode;
24 
25 /**
26  * This property generator computes the properties for the operation
27  * "ImageFunction" dynamically.
28  */
29 class ImageFunctionPropertyGenerator extends PropertyGeneratorImpl {
30 
31     /** Constructor. */
ImageFunctionPropertyGenerator()32     public ImageFunctionPropertyGenerator() {
33         super(new String[] {"COMPLEX"},
34               new Class[] {Boolean.class},
35               new Class[] {RenderedOp.class, RenderableOp.class});
36     }
37 
38     /**
39      * Returns the specified property.
40      *
41      * @param name  Property name.
42      * @param opNode Operation node.
43      */
getProperty(String name, Object opNode)44     public Object getProperty(String name,
45                               Object opNode) {
46         validate(name, opNode);
47 
48         if (name.equalsIgnoreCase("complex")) {
49             if(opNode instanceof RenderedOp) {
50                 RenderedOp op = (RenderedOp)opNode;
51                 ParameterBlock pb = op.getParameterBlock();
52                 ImageFunction imFunc = (ImageFunction)pb.getObjectParameter(0);
53                 return imFunc.isComplex() ? Boolean.TRUE : Boolean.FALSE;
54             } else if(opNode instanceof RenderableOp) {
55                 RenderableOp op = (RenderableOp)opNode;
56                 ParameterBlock pb = op.getParameterBlock();
57                 ImageFunction imFunc = (ImageFunction)pb.getObjectParameter(0);
58                 return imFunc.isComplex() ? Boolean.TRUE : Boolean.FALSE;
59             }
60         }
61 
62         return java.awt.Image.UndefinedProperty;
63     }
64 }
65 
66 
67 /**
68  * An <code>OperationDescriptor</code> describing the "ImageFunction"
69  * operation.
70  *
71  * <p> The "ImageFunction" operation generates an image on the basis of
72  * a functional description provided by an object which is an instance of
73  * a class which implements the <code>ImageFunction</code> interface.
74  * The <i>(x,y)</i> coordinates passed to the <code>getElements()</code>
75  * methods of the <code>ImageFunction</code> object are derived by applying
76  * an optional translation and scaling to the X- and Y-coordinates of the
77  * image.  The image X- and Y-coordinates as usual depend on the values of
78  * the minimum X- and Y- coordinates of the image which need not be zero.
79  * Specifically, the function coordinates passed to <code>getElements()</code>
80  * are calculated from the image coordinates as:
81  *
82  * <pre>
83  * functionX = xScale*(imageX - xTrans);
84  * functionY = yScale*(imageY - yTrans);
85  * </pre>
86  *
87  * This implies that the pixel at coordinates <i>(xTrans,yTrans)</i> will
88  * be assigned the value of the function at <i>(0,0)</i>.
89  *
90  * <p> The number of bands in the destination image must be equal to the
91  * value returned by the <code>getNumElements()</code> method of the
92  * <code>ImageFunction</code> unless the <code>isComplex()</code> method
93  * of the <code>ImageFunction</code> returns <code>true</code> in which
94  * case it will be twice that.  The data type of the destination image is
95  * determined by the <code>SampleModel</code> specified by an
96  * <code>ImageLayout</code> object provided via a hint.  If no layout hint
97  * is provided, the data type will default to single-precision floating point.
98  * The double precision floating point form of the <code>getElements()</code>
99  * method of the <code>ImageFunction</code> will be invoked if and only if
100  * the data type is specified to be <code>double</code>.  For all other data
101  * types the single precision form of <code>getElements()</code> will be
102  * invoked and the destination sample values will be clamped to the data type
103  * of the image.
104  *
105  * <p> The width and height of the image are provided explicitely as
106  * parameters.  These values override the width and height specified via
107  * an <code>ImageLayout</code> if such is provided.
108  *
109  * <p>"ImageFunction" defines a PropertyGenerator that sets the "COMPLEX"
110  * property of the image to <code>java.lang.Boolean.TRUE</code> or
111  * <code>java.lang.Boolean.FALSE</code> depending on whether the
112  * <code>isComplex()</code> method of the <code>ImageFunction</code>
113  * parameter returns <code>true</code> or <code>false</code>, respectively.
114  * This property may be retrieved by calling the <code>getProperty()</code>
115  * method with "COMPLEX" as the property name.
116  *
117  * <p><table border=1>
118  * <caption>Resource List</caption>
119  * <tr><th>Name</th>        <th>Value</th></tr>
120  * <tr><td>GlobalName</td>  <td>ImageFunction</td></tr>
121  * <tr><td>LocalName</td>   <td>ImageFunction</td></tr>
122  * <tr><td>Vendor</td>      <td>com.lightcrafts.media.jai</td></tr>
123  * <tr><td>Description</td> <td>Generates an image from a functional description.</td></tr>
124  * <tr><td>DocURL</td>      <td>http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ImageFunctionDescriptor.html</td></tr>
125  * <tr><td>Version</td>     <td>1.0</td></tr>
126  * <tr><td>arg0Desc</td>    <td>The functional description.</td></tr>
127  * <tr><td>arg1Desc</td>    <td>The image width.</td></tr>
128  * <tr><td>arg2Desc</td>    <td>The image height.</td></tr>
129  * <tr><td>arg3Desc</td>    <td>The X scale factor.</td></tr>
130  * <tr><td>arg4Desc</td>    <td>The Y scale factor.</td></tr>
131  * <tr><td>arg5Desc</td>    <td>The X translation.</td></tr>
132  * <tr><td>arg6Desc</td>    <td>The Y translation.</td></tr>
133  * </table></p>
134  *
135  * <p><table border=1>
136  * <caption>Parameter List</caption>
137  * <tr><th>Name</th>      <th>Class Type</th>
138  *                        <th>Default Value</th></tr>
139  * <tr><td>function</td>  <td>com.lightcrafts.mediax.jai.ImageFunction</td>
140  *                        <td>NO_PARAMETER_DEFAULT</td>
141  * <tr><td>width</td>     <td>java.lang.Integer</td>
142  *                        <td>NO_PARAMETER_DEFAULT</td>
143  * <tr><td>height</td>    <td>java.lang.Integer</td>
144  *                        <td>NO_PARAMETER_DEFAULT</td>
145  * <tr><td>xScale</td>    <td>java.lang.Float</td>
146  *                        <td>1.0F</td>
147  * <tr><td>yScale</td>    <td>java.lang.Float</td>
148  *                        <td>1.0F</td>
149  * <tr><td>xTrans</td>    <td>java.lang.Float</td>
150  *                        <td>0.0F</td>
151  * <tr><td>yTrans</td>    <td>java.lang.Float</td>
152  *                        <td>0.0F</td>
153  * </table></p>
154  *
155  * @see java.awt.geom.AffineTransform
156  * @see com.lightcrafts.mediax.jai.OperationDescriptor
157  * @see com.lightcrafts.mediax.jai.ImageFunction
158  */
159 public class ImageFunctionDescriptor extends OperationDescriptorImpl {
160 
161     /**
162      * The resource strings that provide the general documentation
163      * and specify the parameter list for this operation.
164      */
165     private static final String[][] resources = {
166         {"GlobalName",  "ImageFunction"},
167         {"LocalName",   "ImageFunction"},
168         {"Vendor",      "com.lightcrafts.media.jai"},
169         {"Description", JaiI18N.getString("ImageFunctionDescriptor0")},
170         {"DocURL",      "http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ImageFunctionDescriptor.html"},
171         {"Version",     JaiI18N.getString("DescriptorVersion")},
172         {"arg0Desc",    JaiI18N.getString("ImageFunctionDescriptor1")},
173         {"arg1Desc",    JaiI18N.getString("ImageFunctionDescriptor2")},
174         {"arg2Desc",    JaiI18N.getString("ImageFunctionDescriptor3")},
175         {"arg3Desc",    JaiI18N.getString("ImageFunctionDescriptor4")},
176         {"arg4Desc",    JaiI18N.getString("ImageFunctionDescriptor5")},
177         {"arg5Desc",    JaiI18N.getString("ImageFunctionDescriptor6")},
178         {"arg6Desc",    JaiI18N.getString("ImageFunctionDescriptor7")}
179     };
180 
181     /** The parameter class list for this operation. */
182     private static final Class[] paramClasses = {
183 	com.lightcrafts.mediax.jai.ImageFunction.class,
184         java.lang.Integer.class, java.lang.Integer.class,
185 	java.lang.Float.class, java.lang.Float.class,
186         java.lang.Float.class, java.lang.Float.class
187     };
188 
189     /** The parameter name list for this operation. */
190     private static final String[] paramNames = {
191         "function", "width", "height", "xScale", "yScale", "xTrans", "yTrans"
192     };
193 
194     /** The parameter default value list for this operation. */
195     private static final Object[] paramDefaults = {
196         NO_PARAMETER_DEFAULT, NO_PARAMETER_DEFAULT, NO_PARAMETER_DEFAULT,
197         new Float(1.0F), new Float(1.0F), // unity scale
198         new Float(0.0F), new Float(0.0F)  // zero translation
199     };
200 
201     /** Constructor. */
ImageFunctionDescriptor()202     public ImageFunctionDescriptor() {
203         super(resources, 0, paramClasses, paramNames, paramDefaults);
204     }
205 
206     /**
207      * Returns an array of <code>PropertyGenerators</code> implementing
208      * property inheritance for the "ImageFunction" operation.
209      *
210      * @return  An array of property generators.
211      */
getPropertyGenerators()212     public PropertyGenerator[] getPropertyGenerators() {
213         PropertyGenerator[] pg = new PropertyGenerator[1];
214         pg[0] = new ImageFunctionPropertyGenerator();
215         return pg;
216     }
217 
218 
219     /**
220      * Generates an image from a functional description.
221      *
222      * <p>Creates a <code>ParameterBlockJAI</code> from all
223      * supplied arguments except <code>hints</code> and invokes
224      * {@link JAI#create(String,ParameterBlock,RenderingHints)}.
225      *
226      * @see JAI
227      * @see ParameterBlockJAI
228      * @see RenderedOp
229      *
230      * @param function The functional description.
231      * @param width The image width.
232      * @param height The image height.
233      * @param xScale The X scale factor.
234      * May be <code>null</code>.
235      * @param yScale The Y scale factor.
236      * May be <code>null</code>.
237      * @param xTrans The X translation.
238      * May be <code>null</code>.
239      * @param yTrans The Y translation.
240      * May be <code>null</code>.
241      * @param hints The <code>RenderingHints</code> to use.
242      * May be <code>null</code>.
243      * @return The <code>RenderedOp</code> destination.
244      * @throws IllegalArgumentException if <code>function</code> is <code>null</code>.
245      * @throws IllegalArgumentException if <code>width</code> is <code>null</code>.
246      * @throws IllegalArgumentException if <code>height</code> is <code>null</code>.
247      */
create(ImageFunction function, Integer width, Integer height, Float xScale, Float yScale, Float xTrans, Float yTrans, RenderingHints hints)248     public static RenderedOp create(ImageFunction function,
249                                     Integer width,
250                                     Integer height,
251                                     Float xScale,
252                                     Float yScale,
253                                     Float xTrans,
254                                     Float yTrans,
255                                     RenderingHints hints)  {
256         ParameterBlockJAI pb =
257             new ParameterBlockJAI("ImageFunction",
258                                   RenderedRegistryMode.MODE_NAME);
259 
260         pb.setParameter("function", function);
261         pb.setParameter("width", width);
262         pb.setParameter("height", height);
263         pb.setParameter("xScale", xScale);
264         pb.setParameter("yScale", yScale);
265         pb.setParameter("xTrans", xTrans);
266         pb.setParameter("yTrans", yTrans);
267 
268         return JAI.create("ImageFunction", pb, hints);
269     }
270 }
271