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