001: /*
002: * $RCSfile: TranslateDescriptor.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:45 $
010: * $State: Exp $
011: */
012: package javax.media.jai.operator;
013:
014: import com.sun.media.jai.util.PropertyGeneratorImpl;
015: import java.awt.Rectangle;
016: import java.awt.RenderingHints;
017: import java.awt.geom.AffineTransform;
018: import java.awt.image.RenderedImage;
019: import java.awt.image.renderable.ParameterBlock;
020: import java.awt.image.renderable.RenderableImage;
021: import javax.media.jai.GeometricOpImage;
022: import javax.media.jai.Interpolation;
023: import javax.media.jai.InterpolationNearest;
024: import javax.media.jai.JAI;
025: import javax.media.jai.OperationDescriptorImpl;
026: import javax.media.jai.ParameterBlockJAI;
027: import javax.media.jai.PlanarImage;
028: import javax.media.jai.PropertyGenerator;
029: import javax.media.jai.ROI;
030: import javax.media.jai.ROIShape;
031: import javax.media.jai.RenderableOp;
032: import javax.media.jai.RenderedOp;
033: import javax.media.jai.registry.RenderableRegistryMode;
034: import javax.media.jai.registry.RenderedRegistryMode;
035:
036: /**
037: * This property generator computes the properties for the operation
038: * "Translate" dynamically.
039: */
040: class TranslatePropertyGenerator extends PropertyGeneratorImpl {
041:
042: /** Constructor. */
043: public TranslatePropertyGenerator() {
044: super (new String[] { "ROI" }, new Class[] { ROI.class },
045: new Class[] { RenderedOp.class });
046: }
047:
048: /**
049: * Returns the specified property.
050: *
051: * @param name Property name.
052: * @param opNode Operation node.
053: */
054: public Object getProperty(String name, Object opNode) {
055: validate(name, opNode);
056:
057: if (opNode instanceof RenderedOp
058: && name.equalsIgnoreCase("roi")) {
059: RenderedOp op = (RenderedOp) opNode;
060:
061: ParameterBlock pb = op.getParameterBlock();
062:
063: // Retrieve the rendered source image and its ROI.
064: RenderedImage src = pb.getRenderedSource(0);
065: Object property = src.getProperty("ROI");
066: if (property == null
067: || property
068: .equals(java.awt.Image.UndefinedProperty)
069: || !(property instanceof ROI)) {
070: return java.awt.Image.UndefinedProperty;
071: }
072: ROI srcROI = (ROI) property;
073:
074: // Retrieve the Interpolation object.
075: Interpolation interp = (Interpolation) pb
076: .getObjectParameter(2);
077:
078: // Determine the effective source bounds.
079: Rectangle srcBounds = null;
080: PlanarImage dst = op.getRendering();
081: if (dst instanceof GeometricOpImage
082: && ((GeometricOpImage) dst).getBorderExtender() == null) {
083: srcBounds = new Rectangle(src.getMinX()
084: + interp.getLeftPadding(), src.getMinY()
085: + interp.getTopPadding(), src.getWidth()
086: - interp.getWidth() + 1, src.getHeight()
087: - interp.getHeight() + 1);
088: } else {
089: srcBounds = new Rectangle(src.getMinX(), src.getMinY(),
090: src.getWidth(), src.getHeight());
091: }
092:
093: // If necessary, clip the ROI to the effective source bounds.
094: if (!srcBounds.contains(srcROI.getBounds())) {
095: srcROI = srcROI.intersect(new ROIShape(srcBounds));
096: }
097:
098: // Retrieve the translation values.
099: float tx = pb.getFloatParameter(0);
100: float ty = pb.getFloatParameter(1);
101:
102: // Create a transform representing the translation.
103: AffineTransform transform = AffineTransform
104: .getTranslateInstance((double) tx, (double) ty);
105: // Create the translated ROI.
106: ROI dstROI = srcROI.transform(transform);
107:
108: // Retrieve the destination bounds.
109: Rectangle dstBounds = op.getBounds();
110:
111: // If necessary, clip the warped ROI to the destination bounds.
112: if (!dstBounds.contains(dstROI.getBounds())) {
113: dstROI = dstROI.intersect(new ROIShape(dstBounds));
114: }
115:
116: // Return the warped and possibly clipped ROI.
117: return dstROI;
118: }
119:
120: return java.awt.Image.UndefinedProperty;
121: }
122: }
123:
124: /**
125: * An <code>OperationDescriptor</code> describing the "Translate" operation.
126: *
127: * <p> The "Translate" operation copies an image to a new location
128: * in the plane.
129: *
130: * <p> For each pixel (x, y) of the destination, the source value at
131: * the fractional subpixel position (x - xTrans, y - yTrans) is
132: * constructed by means of an Interpolation object and written to the
133: * destination. If both xTrans and yTrans are integral, the operation
134: * simply "wraps" its source image to change the image's position in
135: * the coordinate plane.
136: *
137: * <p> It may be noted that the minX, minY, width and height hints as
138: * specified through the <code>JAI.KEY_IMAGE_LAYOUT</code> hint in the
139: * <code>RenderingHints</code> object are not honored, as this operator
140: * calculates the destination image bounds itself. The other
141: * <code>ImageLayout</code> hints, like tileWidth and tileHeight,
142: * however are honored.
143: *
144: * <p> It should be noted that this operation automatically adds a
145: * value of <code>Boolean.TRUE</code> for the
146: * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> to the given
147: * <code>configuration</code> so that the operation is performed
148: * on the pixel values instead of being performed on the indices into
149: * the color map if the source(s) have an <code>IndexColorModel</code>.
150: * This addition will take place only if a value for the
151: * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> has not already been
152: * provided by the user. Note that the <code>configuration</code> Map
153: * is cloned before the new hint is added to it. The operation can be
154: * smart about the value of the <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code>
155: * <code>RenderingHints</code>, i.e. while the default value for the
156: * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> is
157: * <code>Boolean.TRUE</code>, in some cases the operator could set the
158: * default.
159: *
160: * <p> "Translate" defines a PropertyGenerator that performs an
161: * identical transformation on the "ROI" property of the source image,
162: * which can be retrieved by calling the <code>getProperty</code>
163: * method with "ROI" as the property name.
164: *
165: * <p><table border=1>
166: * <caption>Resource List</caption>
167: * <tr><th>Name</th> <th>Value</th></tr>
168: * <tr><td>GlobalName</td> <td>Translate</td></tr>
169: * <tr><td>LocalName</td> <td>Translate</td></tr>
170: * <tr><td>Vendor</td> <td>com.sun.media.jai</td></tr>
171: * <tr><td>Description</td> <td>Moves an image to a new location.</td></tr>
172: * <tr><td>DocURL</td> <td>http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/TranslateDescriptor.html</td></tr>
173: * <tr><td>Version</td> <td>1.0</td></tr>
174: * <tr><td>arg0Desc</td> <td>The displacement in X direction.</td></tr>
175: * <tr><td>arg1Desc</td> <td>The displacement in Y direction.</td></tr>
176: * <tr><td>arg2Desc</td> <td>The interpolation method.</td></tr>
177: * </table></p>
178: *
179: * <p><table border=1>
180: * <caption>Parameter List</caption>
181: * <tr><th>Name</th> <th>Class Type</th>
182: * <th>Default Value</th></tr>
183: * <tr><td>xTrans</td> <td>java.lang.Float</td>
184: * <td>0.0F</td>
185: * <tr><td>yTrans</td> <td>java.lang.Float</td>
186: * <td>0.0F</td>
187: * <tr><td>interpolation</td> <td>javax.media.jai.Interpolation</td>
188: * <td>InterpolationNearest</td>
189: * </table></p>
190: *
191: * @see javax.media.jai.Interpolation
192: * @see javax.media.jai.OperationDescriptor
193: */
194: public class TranslateDescriptor extends OperationDescriptorImpl {
195:
196: /**
197: * The resource strings that provide the general documentation and
198: * specify the parameter list for the "Translate" operation.
199: */
200: private static final String[][] resources = {
201: { "GlobalName", "Translate" },
202: { "LocalName", "Translate" },
203: { "Vendor", "com.sun.media.jai" },
204: { "Description", JaiI18N.getString("TranslateDescriptor0") },
205: {
206: "DocURL",
207: "http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/TranslateDescriptor.html" },
208: { "Version", JaiI18N.getString("DescriptorVersion") },
209: { "arg0Desc", JaiI18N.getString("TranslateDescriptor1") },
210: { "arg1Desc", JaiI18N.getString("TranslateDescriptor2") },
211: { "arg2Desc", JaiI18N.getString("TranslateDescriptor3") } };
212:
213: /** The parameter names for the "Translate" operation. */
214: private static final String[] paramNames = { "xTrans", "yTrans",
215: "interpolation" };
216:
217: /** The parameter class types for the "Translate" operation. */
218: private static final Class[] paramClasses = {
219: java.lang.Float.class, java.lang.Float.class,
220: javax.media.jai.Interpolation.class };
221:
222: /** The parameter default values for the "Translate" operation. */
223: private static final Object[] paramDefaults = { new Float(0.0F),
224: new Float(0.0F),
225: Interpolation.getInstance(Interpolation.INTERP_NEAREST) };
226:
227: /** Constructor. */
228: public TranslateDescriptor() {
229: super (resources, 1, paramClasses, paramNames, paramDefaults);
230: }
231:
232: /** Returns <code>true</code> since renderable operation is supported. */
233: public boolean isRenderableSupported() {
234: return true;
235: }
236:
237: /**
238: * Returns an array of <code>PropertyGenerators</code> implementing
239: * property inheritance for the "Translate" operation
240: *
241: * @return An array of property generators.
242: */
243: public PropertyGenerator[] getPropertyGenerators() {
244: PropertyGenerator[] pg = new PropertyGenerator[1];
245: pg[0] = new TranslatePropertyGenerator();
246: return pg;
247: }
248:
249: /**
250: * Moves an image to a new location.
251: *
252: * <p>Creates a <code>ParameterBlockJAI</code> from all
253: * supplied arguments except <code>hints</code> and invokes
254: * {@link JAI#create(String,ParameterBlock,RenderingHints)}.
255: *
256: * @see JAI
257: * @see ParameterBlockJAI
258: * @see RenderedOp
259: *
260: * @param source0 <code>RenderedImage</code> source 0.
261: * @param xTrans The displacement in X direction.
262: * May be <code>null</code>.
263: * @param yTrans The displacement in Y direction.
264: * May be <code>null</code>.
265: * @param interpolation The interpolation method.
266: * May be <code>null</code>.
267: * @param hints The <code>RenderingHints</code> to use.
268: * May be <code>null</code>.
269: * @return The <code>RenderedOp</code> destination.
270: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
271: */
272: public static RenderedOp create(RenderedImage source0,
273: Float xTrans, Float yTrans, Interpolation interpolation,
274: RenderingHints hints) {
275: ParameterBlockJAI pb = new ParameterBlockJAI("Translate",
276: RenderedRegistryMode.MODE_NAME);
277:
278: pb.setSource("source0", source0);
279:
280: pb.setParameter("xTrans", xTrans);
281: pb.setParameter("yTrans", yTrans);
282: pb.setParameter("interpolation", interpolation);
283:
284: return JAI.create("Translate", pb, hints);
285: }
286:
287: /**
288: * Moves an image to a new location.
289: *
290: * <p>Creates a <code>ParameterBlockJAI</code> from all
291: * supplied arguments except <code>hints</code> and invokes
292: * {@link JAI#createRenderable(String,ParameterBlock,RenderingHints)}.
293: *
294: * @see JAI
295: * @see ParameterBlockJAI
296: * @see RenderableOp
297: *
298: * @param source0 <code>RenderableImage</code> source 0.
299: * @param xTrans The displacement in X direction.
300: * May be <code>null</code>.
301: * @param yTrans The displacement in Y direction.
302: * May be <code>null</code>.
303: * @param interpolation The interpolation method.
304: * May be <code>null</code>.
305: * @param hints The <code>RenderingHints</code> to use.
306: * May be <code>null</code>.
307: * @return The <code>RenderableOp</code> destination.
308: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
309: */
310: public static RenderableOp createRenderable(
311: RenderableImage source0, Float xTrans, Float yTrans,
312: Interpolation interpolation, RenderingHints hints) {
313: ParameterBlockJAI pb = new ParameterBlockJAI("Translate",
314: RenderableRegistryMode.MODE_NAME);
315:
316: pb.setSource("source0", source0);
317:
318: pb.setParameter("xTrans", xTrans);
319: pb.setParameter("yTrans", yTrans);
320: pb.setParameter("interpolation", interpolation);
321:
322: return JAI.createRenderable("Translate", pb, hints);
323: }
324: }
|