001: /*
002: * $RCSfile: FormatDescriptor.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:36 $
010: * $State: Exp $
011: */
012: package javax.media.jai.operator;
013:
014: import java.awt.RenderingHints;
015: import java.awt.image.DataBuffer;
016: import java.awt.image.RenderedImage;
017: import java.awt.image.renderable.ParameterBlock;
018: import java.awt.image.renderable.RenderableImage;
019: import javax.media.jai.JAI;
020: import javax.media.jai.OperationDescriptorImpl;
021: import javax.media.jai.ParameterBlockJAI;
022: import javax.media.jai.RenderableOp;
023: import javax.media.jai.RenderedOp;
024: import javax.media.jai.registry.RenderableRegistryMode;
025: import javax.media.jai.registry.RenderedRegistryMode;
026:
027: /**
028: * An <code>OperationDescriptor</code> describing the "Format" operation.
029: *
030: * <p> The "Format" operation performs reformatting on an image. It
031: * is capable of casting the pixel values of an image to a given data
032: * type, replacing the SampleModel and ColorModel of an image, and
033: * restructuring the image's tile grid layout. The pixel values of
034: * the destination image are defined by the pseudocode:
035: *
036: * <pre>dst[x][y][b] = cast(src[x][y][b], dataType)</pre>
037: *
038: * where "dataType" is one of the constants TYPE_BYTE, TYPE_SHORT,
039: * TYPE_USHORT, TYPE_INT, TYPE_FLOAT, or TYPE_DOUBLE from
040: * <code>java.awt.image.DataBuffer</code>.
041: *
042: * <p> The output SampleModel, ColorModel and tile grid layout are
043: * specified by passing an ImageLayout object as a RenderingHint named
044: * "ImageLayout". The output image will have a SampleModel compatible
045: * with the one specified in the layout hint wherever possible;
046: * however, for output data types of <code>float</code> and
047: * </code>double a <code>ComponentSampleModel</code> will be used
048: * regardless of the value of the hint parameter.
049: *
050: * <p> One of the common uses of the format operator is to cast the
051: * pixel values of an image to a given data type. In such a case, if
052: * the source image provided has an <code>IndexColorModel</code>, a
053: * <code>RenderingHints</code> object for
054: * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> with the value of
055: * <code>Boolean.TRUE</code> will automatically be added to the
056: * configuration <code>Map</code> for the operation. This addition
057: * will only take place if a value for the
058: * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> has not already been
059: * provided by the user. Note that the <code>configuration</code> Map
060: * is cloned before the new hint is added to it. Due to the addition
061: * of this new <code>RenderingHint</code>, using the "format" operation
062: * with source(s) that have an <code>IndexColorModel</code> will cause
063: * the destination to have an expanded non-<code>IndexColorModel</code>
064: * <code>ColorModel</code>. This expansion ensures that the conversion
065: * to a different data type, <code>ColorModel</code> or
066: * <code>SampleModel</code> happens correctly such that the indices
067: * into the color map (for <code>IndexColorModel</code> images) are
068: * not treated as pixel data. If the format operator is not being used
069: * to cast the pixel values of an image to a given data type, the
070: * expansion will not take place, the resultant image will still have
071: * an <code>IndexColorModel</code>.
072: *
073: * <p> The ImageLayout may also specify a tile grid origin and size
074: * which will be respected.
075: *
076: * <p> The typecasting performed by the <code>Format</code> function
077: * is defined by the following set of expressions, dependent on the
078: * data types of the source and destination. Casting an image to its
079: * current data type is a no-op. See <a
080: * href=http://java.sun.com/docs/books/jls/html/5.doc.html#25222> The
081: * Java Language Specification</a> for the definition of type
082: * conversions between primitive types.
083: *
084: * <p> In most cases, it is not necessary to explictly perform widening
085: * typecasts since they will be performed automatically by image
086: * operators when handed source images having different datatypes.
087: *
088: * <p><table border=1>
089: * <tr><th>Source Type</th> <th>Destination Type</th> <th>Action</th></tr>
090: * <tr><td>BYTE</td> <td>SHORT</td> <td>(short)(x & 0xff)</td></tr>
091: * <tr><td>BYTE</td> <td>USHORT</td> <td>(short)(x & 0xff)</td></tr>
092: * <tr><td>BYTE</td> <td>INT</td> <td>(int)(x & 0xff)</td></tr>
093: * <tr><td>BYTE</td> <td>FLOAT</td> <td>(float)(x & 0xff)</td></tr>
094: * <tr><td>BYTE</td> <td>DOUBLE</td> <td>(double)(x & 0xff)</td></tr>
095: * <tr><td>SHORT</td> <td>BYTE</td> <td>(byte)clamp((int)x, 0, 255)</td></tr>
096: * <tr><td>SHORT</td> <td>USHORT</td> <td>(short)clamp((int)x, 0, 32767)</td></tr>
097: * <tr><td>SHORT</td> <td>INT</td> <td>(int)x</td></tr>
098: * <tr><td>SHORT</td> <td>FLOAT</td> <td>(float)x</td></tr>
099: * <tr><td>SHORT</td> <td>DOUBLE</td> <td>(double)x</td></tr>
100: * <tr><td>USHORT</td> <td>BYTE</td> <td>(byte)clamp((int)x & 0xffff, 0, 255)</td></tr>
101: * <tr><td>USHORT</td> <td>SHORT</td> <td>(short)clamp((int)x & 0xffff, 0, 32767)</td></tr>
102: * <tr><td>USHORT</td> <td>INT</td> <td>(int)(x & 0xffff)</td></tr>
103: * <tr><td>USHORT</td> <td>FLOAT</td> <td>(float)(x & 0xffff)</td></tr>
104: * <tr><td>USHORT</td> <td>DOUBLE</td> <td>(double)(x & 0xffff)</td></tr>
105: * <tr><td>INT</td> <td>BYTE</td> <td>(byte)clamp(x, 0, 255)</td></tr>
106: * <tr><td>INT</td> <td>SHORT</td> <td>(short)clamp(x, -32768, 32767)</td></tr>
107: * <tr><td>INT</td> <td>USHORT</td> <td>(short)clamp(x, 0, 65535)</td></tr>
108: * <tr><td>INT</td> <td>FLOAT</td> <td>(float)x</td></tr>
109: * <tr><td>INT</td> <td>DOUBLE</td> <td>(double)x</td></tr>
110: * <tr><td>FLOAT</td> <td>BYTE</td> <td>(byte)clamp((int)x, 0, 255)</td></tr>
111: * <tr><td>FLOAT</td> <td>SHORT</td> <td>(short)clamp((int)x, -32768, 32767)</td></tr>
112: * <tr><td>FLOAT</td> <td>USHORT</td> <td>(short)clamp((int)x, 0, 65535)</td></tr>
113: * <tr><td>FLOAT</td> <td>INT</td> <td>(int)x</td></tr>
114: * <tr><td>FLOAT</td> <td>DOUBLE</td> <td>(double)x</td></tr>
115: * <tr><td>DOUBLE</td> <td>BYTE</td> <td>(byte)clamp((int)x, 0, 255)</td></tr>
116: * <tr><td>DOUBLE</td> <td>SHORT</td> <td>(short)clamp((int)x, -32768, 32767)</td></tr>
117: * <tr><td>DOUBLE</td> <td>USHORT</td> <td>(short)clamp((int)x, 0, 65535)</td></tr>
118: * <tr><td>DOUBLE</td> <td>INT</td> <td>(int)x</td></tr>
119: * <tr><td>DOUBLE</td> <td>FLOAT</td> <td>(float)x</td></tr>
120: * </table></p>
121: *
122: * The <code>clamp</code> function may be defined as:
123: * <pre>
124: * int clamp(int x, int low, int high) {
125: * return (x < low) ? low : ((x > high) ? high : x);
126: * }
127: * </pre>
128: *
129: * <p><table border=1>
130: * <caption>Resource List</caption>
131: * <tr><th>Name</th> <th>Value</th></tr>
132: * <tr><td>GlobalName</td> <td>Format</td></tr>
133: * <tr><td>LocalName</td> <td>Format</td></tr>
134: * <tr><td>Vendor</td> <td>com.sun.media.jai</td></tr>
135: * <tr><td>Description</td> <td>Reformats an image.</td></tr>
136: * <tr><td>DocURL</td> <td>http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/FormatDescriptor.html</td></tr>
137: * <tr><td>Version</td> <td>1.0</td></tr>
138: * <tr><td>arg0Desc</td> <td>The output data type (from java.awt.image.DataBuffer).</td></tr>
139: * </table></p>
140: *
141: * <p><table border=1>
142: * <caption>Parameter List</caption>
143: * <tr><th>Name</th> <th>Class Type</th>
144: * <th>Default Value</th></tr>
145: * <tr><td>dataType</td> <td>java.lang.Integer</td>
146: * <td>DataBuffer.TYPE_BYTE</td>
147: * </table></p>
148: *
149: * @see java.awt.image.DataBuffer
150: * @see javax.media.jai.ImageLayout
151: * @see javax.media.jai.OperationDescriptor
152: */
153: public class FormatDescriptor extends OperationDescriptorImpl {
154:
155: /**
156: * The resource strings that provide the general documentation
157: * and specify the parameter list for this operation.
158: */
159: private static final String[][] resources = {
160: { "GlobalName", "Format" },
161: { "LocalName", "Format" },
162: { "Vendor", "com.sun.media.jai" },
163: { "Description", JaiI18N.getString("FormatDescriptor0") },
164: {
165: "DocURL",
166: "http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/FormatDescriptor.html" },
167: { "Version", JaiI18N.getString("DescriptorVersion") },
168: { "arg0Desc",
169: "The output data type (from java.awt.image.DataBuffer)." } };
170:
171: /** The parameter class list for this operation. */
172: private static final Class[] paramClasses = { java.lang.Integer.class };
173:
174: /** The parameter name list for this operation. */
175: private static final String[] paramNames = { "dataType" };
176:
177: /** The parameter default value list for this operation. */
178: private static final Object[] paramDefaults = { new Integer(
179: DataBuffer.TYPE_BYTE) };
180:
181: /** Constructor. */
182: public FormatDescriptor() {
183: super (resources, 1, paramClasses, paramNames, paramDefaults);
184: }
185:
186: /** Returns <code>true</code> since renderable operation is supported. */
187: public boolean isRenderableSupported() {
188: return true;
189: }
190:
191: /**
192: * Returns the minimum legal value of a specified numeric parameter
193: * for this operation.
194: */
195: public Number getParamMinValue(int index) {
196: if (index == 0) {
197: return new Integer(DataBuffer.TYPE_BYTE);
198: } else {
199: throw new ArrayIndexOutOfBoundsException();
200: }
201: }
202:
203: /**
204: * Returns the maximum legal value of a specified numeric parameter
205: * for this operation.
206: */
207: public Number getParamMaxValue(int index) {
208: if (index == 0) {
209: return new Integer(DataBuffer.TYPE_DOUBLE);
210: } else {
211: throw new ArrayIndexOutOfBoundsException();
212: }
213: }
214:
215: /**
216: * Reformats an image.
217: *
218: * <p>Creates a <code>ParameterBlockJAI</code> from all
219: * supplied arguments except <code>hints</code> and invokes
220: * {@link JAI#create(String,ParameterBlock,RenderingHints)}.
221: *
222: * @see JAI
223: * @see ParameterBlockJAI
224: * @see RenderedOp
225: *
226: * @param source0 <code>RenderedImage</code> source 0.
227: * @param dataType The output data type (from java.awt.image.DataBuffer).
228: * May be <code>null</code>.
229: * @param hints The <code>RenderingHints</code> to use.
230: * May be <code>null</code>.
231: * @return The <code>RenderedOp</code> destination.
232: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
233: */
234: public static RenderedOp create(RenderedImage source0,
235: Integer dataType, RenderingHints hints) {
236: ParameterBlockJAI pb = new ParameterBlockJAI("Format",
237: RenderedRegistryMode.MODE_NAME);
238:
239: pb.setSource("source0", source0);
240:
241: pb.setParameter("dataType", dataType);
242:
243: return JAI.create("Format", pb, hints);
244: }
245:
246: /**
247: * Reformats an image.
248: *
249: * <p>Creates a <code>ParameterBlockJAI</code> from all
250: * supplied arguments except <code>hints</code> and invokes
251: * {@link JAI#createRenderable(String,ParameterBlock,RenderingHints)}.
252: *
253: * @see JAI
254: * @see ParameterBlockJAI
255: * @see RenderableOp
256: *
257: * @param source0 <code>RenderableImage</code> source 0.
258: * @param dataType The output data type (from java.awt.image.DataBuffer).
259: * May be <code>null</code>.
260: * @param hints The <code>RenderingHints</code> to use.
261: * May be <code>null</code>.
262: * @return The <code>RenderableOp</code> destination.
263: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
264: */
265: public static RenderableOp createRenderable(
266: RenderableImage source0, Integer dataType,
267: RenderingHints hints) {
268: ParameterBlockJAI pb = new ParameterBlockJAI("Format",
269: RenderableRegistryMode.MODE_NAME);
270:
271: pb.setSource("source0", source0);
272:
273: pb.setParameter("dataType", dataType);
274:
275: return JAI.createRenderable("Format", pb, hints);
276: }
277: }
|