001: /*
002: * $RCSfile: TransposeDescriptor.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:46 $
010: * $State: Exp $
011: */
012: package javax.media.jai.operator;
013:
014: import com.sun.media.jai.util.PropertyGeneratorImpl;
015: import java.awt.RenderingHints;
016: import java.awt.geom.AffineTransform;
017: import java.awt.image.RenderedImage;
018: import java.awt.image.renderable.ParameterBlock;
019: import java.awt.image.renderable.RenderableImage;
020: import javax.media.jai.EnumeratedParameter;
021: import javax.media.jai.Interpolation;
022: import javax.media.jai.JAI;
023: import javax.media.jai.OperationDescriptorImpl;
024: import javax.media.jai.ParameterBlockJAI;
025: import javax.media.jai.PlanarImage;
026: import javax.media.jai.PropertyGenerator;
027: import javax.media.jai.ROI;
028: import javax.media.jai.RenderableOp;
029: import javax.media.jai.RenderedOp;
030: import javax.media.jai.operator.TransposeType;
031: import javax.media.jai.registry.RenderableRegistryMode;
032: import javax.media.jai.registry.RenderedRegistryMode;
033:
034: /**
035: * This property generator computes the properties for the operation
036: * "Transpose" dynamically.
037: */
038: class TransposePropertyGenerator extends PropertyGeneratorImpl {
039:
040: /** Constructor. */
041: public TransposePropertyGenerator() {
042: super (new String[] { "ROI" }, new Class[] { ROI.class },
043: new Class[] { RenderedOp.class });
044: }
045:
046: /**
047: * Returns the specified property.
048: *
049: * @param name Property name.
050: * @param opNode Operation node.
051: */
052: public Object getProperty(String name, Object opNode) {
053: validate(name, opNode);
054:
055: if (opNode instanceof RenderedOp
056: && name.equalsIgnoreCase("roi")) {
057: RenderedOp op = (RenderedOp) opNode;
058:
059: ParameterBlock pb = op.getParameterBlock();
060:
061: // Retrieve the rendered source image and its ROI.
062: PlanarImage src = (PlanarImage) pb.getRenderedSource(0);
063: Object property = src.getProperty("ROI");
064: if (property == null
065: || property
066: .equals(java.awt.Image.UndefinedProperty)
067: || !(property instanceof ROI)) {
068: return java.awt.Image.UndefinedProperty;
069: }
070:
071: // Return undefined also if source ROI is empty.
072: ROI srcROI = (ROI) property;
073: if (srcROI.getBounds().isEmpty()) {
074: return java.awt.Image.UndefinedProperty;
075: }
076:
077: /// This should really create a proper AffineTransform
078: /// and transform the ROI with it to avoid forcing
079: /// ROI.getAsImage to be called.
080:
081: // Retrieve the transpose type and create a nearest neighbor
082: // Interpolation object.
083: TransposeType transposeType = (TransposeType) pb
084: .getObjectParameter(0);
085: Interpolation interp = Interpolation
086: .getInstance(Interpolation.INTERP_NEAREST);
087:
088: // Return the transposed ROI.
089: return new ROI(JAI.create("transpose", srcROI.getAsImage(),
090: transposeType));
091: }
092:
093: return java.awt.Image.UndefinedProperty;
094: }
095: }
096:
097: /**
098: * An <code>OperationDescriptor</code> describing the "Transpose" operation.
099: *
100: * <p> The "Transpose" operation performs the following operations:
101: *
102: * <ul>
103: *
104: * <li> Flip an image across an imaginary horizontal line that runs
105: * through the center of the image (FLIP_VERTICAL).</li>
106: *
107: * <li> Flip an image across an imaginary vertical line that runs
108: * through the center of the image (FLIP_HORIZONTAL).</li>
109: *
110: * <li> Flip an image across its main diagonal that runs from the upper
111: * left to the lower right corner (FLIP_DIAGONAL).</li>
112: *
113: * <li> Flip an image across its main antidiagonal that runs from the
114: * upper right to the lower left corner(FLIP_ANTIDIAGONAL).</li>
115: *
116: * <li> Rotate an image clockwise by 90, 180, or 270 degrees
117: * (ROTATE_90, ROTATE_180, ROTATE_270).</li>
118: *
119: * </ul>
120: *
121: * <p> In all cases, the resulting image will have the same origin (as
122: * defined by the return values of its <code>getMinX()</code> and
123: * <code>getMinY()</code> methods) as the source image.
124: *
125: * <p> It should be noted that this operation automatically adds a
126: * value of <code>Boolean.TRUE</code> for the
127: * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> to the given
128: * <code>configuration</code> so that the operation is performed
129: * on the pixel values instead of being performed on the indices into
130: * the color map if the source(s) have an <code>IndexColorModel</code>.
131: * This addition will take place only if a value for the
132: * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> has not already been
133: * provided by the user. Note that the <code>configuration</code> Map
134: * is cloned before the new hint is added to it. The operation can be
135: * smart about the value of the <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code>
136: * <code>RenderingHints</code>, i.e. while the default value for the
137: * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> is
138: * <code>Boolean.TRUE</code>, in some cases the operator could set the
139: * default.
140: *
141: * <p> "Transpose" defines a PropertyGenerator that
142: * performs an identical transformation on the "ROI" property of the
143: * source image, which can be retrieved by calling the
144: * <code>getProperty</code> method with "ROI" as the property name.
145: *
146: * <p><table border=1>
147: * <caption>Resource List</caption>
148: * <tr><th>Name</th> <th>Value</th></tr>
149: * <tr><td>GlobalName</td> <td>transpose</td></tr>
150: * <tr><td>LocalName</td> <td>transpose</td></tr>
151: * <tr><td>Vendor</td> <td>com.sun.media.jai</td></tr>
152: * <tr><td>Description</td> <td>Reflects an image in a specified direction
153: * or rotates an image in multiples of 90
154: * degrees.</td></tr>
155: * <tr><td>DocURL</td> <td>http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/TransposeDescriptor.html</td></tr>
156: * <tr><td>Version</td> <td>1.0</td></tr>
157: * <tr><td>arg0Desc</td> <td>The type of flip operation
158: * to be performed.</td></tr>
159: * </table></p>
160: *
161: * <p><table border=1>
162: * <caption>Parameter List</caption>
163: * <tr><th>Name</th> <th>Class Type</th>
164: * <th>Default Value</th></tr>
165: * <tr><td>type</td> <td>javax.media.jai.operator.TransposeType</td>
166: * <td>NO_PARAMETER_DEFAULT</td>
167: * </table></p>
168: *
169: * @see javax.media.jai.OperationDescriptor
170: * @see TransposeType
171: */
172: public class TransposeDescriptor extends OperationDescriptorImpl {
173:
174: public static final TransposeType FLIP_VERTICAL = new TransposeType(
175: "FLIP_VERTICAL", 0);
176: public static final TransposeType FLIP_HORIZONTAL = new TransposeType(
177: "FLIP_HORIZONTAL", 1);
178: public static final TransposeType FLIP_DIAGONAL = new TransposeType(
179: "FLIP_DIAGONAL", 2);
180: public static final TransposeType FLIP_ANTIDIAGONAL = new TransposeType(
181: "FLIP_ANTIDIAGONAL", 3);
182: public static final TransposeType ROTATE_90 = new TransposeType(
183: "ROTATE_90", 4);
184: public static final TransposeType ROTATE_180 = new TransposeType(
185: "ROTATE_180", 5);
186: public static final TransposeType ROTATE_270 = new TransposeType(
187: "ROTATE_270", 6);
188:
189: /**
190: * The resource strings that provide the general documentation
191: * and specify the parameter list for this operation.
192: */
193: private static final String[][] resources = {
194: { "GlobalName", "Transpose" },
195: { "LocalName", "Transpose" },
196: { "Vendor", "com.sun.media.jai" },
197: { "Description", JaiI18N.getString("TransposeDescriptor0") },
198: {
199: "DocURL",
200: "http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/TransposeDescriptor.html" },
201: { "Version", JaiI18N.getString("DescriptorVersion2") },
202: { "arg0Desc", JaiI18N.getString("TransposeDescriptor1") } };
203:
204: /** The parameter class list for this operation. */
205: private static final Class[] paramClasses = { TransposeType.class };
206:
207: /** The parameter name list for this operation. */
208: private static final String[] paramNames = { "type" };
209:
210: /** The parameter default value list for this operation. */
211: private static final Object[] paramDefaults = { NO_PARAMETER_DEFAULT };
212:
213: /** Constructor. */
214: public TransposeDescriptor() {
215: super (resources, 1, paramClasses, paramNames, paramDefaults);
216: }
217:
218: /** Returns <code>true</code> since renderable operation is supported. */
219: public boolean isRenderableSupported() {
220: return true;
221: }
222:
223: /**
224: * Returns an array of <code>PropertyGenerators</code> implementing
225: * property inheritance for the "Transpose" operation.
226: *
227: * @return An array of property generators.
228: */
229: public PropertyGenerator[] getPropertyGenerators() {
230: PropertyGenerator[] pg = new PropertyGenerator[1];
231: pg[0] = new TransposePropertyGenerator();
232: return pg;
233: }
234:
235: /**
236: * Reflects an image in a specified direction or rotates an image in multiples of 90 degrees.
237: *
238: * <p>Creates a <code>ParameterBlockJAI</code> from all
239: * supplied arguments except <code>hints</code> and invokes
240: * {@link JAI#create(String,ParameterBlock,RenderingHints)}.
241: *
242: * @see JAI
243: * @see ParameterBlockJAI
244: * @see RenderedOp
245: *
246: * @param source0 <code>RenderedImage</code> source 0.
247: * @param type The The type of flip operation to be performed.
248: * @param hints The <code>RenderingHints</code> to use.
249: * May be <code>null</code>.
250: * @return The <code>RenderedOp</code> destination.
251: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
252: * @throws IllegalArgumentException if <code>type</code> is <code>null</code>.
253: */
254: public static RenderedOp create(RenderedImage source0,
255: TransposeType type, RenderingHints hints) {
256: ParameterBlockJAI pb = new ParameterBlockJAI("Transpose",
257: RenderedRegistryMode.MODE_NAME);
258:
259: pb.setSource("source0", source0);
260:
261: pb.setParameter("type", type);
262:
263: return JAI.create("Transpose", pb, hints);
264: }
265:
266: /**
267: * Reflects an image in a specified direction or rotates an image in multiples of 90 degrees.
268: *
269: * <p>Creates a <code>ParameterBlockJAI</code> from all
270: * supplied arguments except <code>hints</code> and invokes
271: * {@link JAI#createRenderable(String,ParameterBlock,RenderingHints)}.
272: *
273: * @see JAI
274: * @see ParameterBlockJAI
275: * @see RenderableOp
276: *
277: * @param source0 <code>RenderableImage</code> source 0.
278: * @param type The The type of flip operation to be performed.
279: * @param hints The <code>RenderingHints</code> to use.
280: * May be <code>null</code>.
281: * @return The <code>RenderableOp</code> destination.
282: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
283: * @throws IllegalArgumentException if <code>type</code> is <code>null</code>.
284: */
285: public static RenderableOp createRenderable(
286: RenderableImage source0, TransposeType type,
287: RenderingHints hints) {
288: ParameterBlockJAI pb = new ParameterBlockJAI("Transpose",
289: RenderableRegistryMode.MODE_NAME);
290:
291: pb.setSource("source0", source0);
292:
293: pb.setParameter("type", type);
294:
295: return JAI.createRenderable("Transpose", pb, hints);
296: }
297: }
|