001: /*
002: * $RCSfile: ClampDescriptor.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:31 $
010: * $State: Exp $
011: */
012: package javax.media.jai.operator;
013:
014: import java.awt.RenderingHints;
015: import java.awt.image.RenderedImage;
016: import java.awt.image.renderable.ParameterBlock;
017: import java.awt.image.renderable.RenderableImage;
018: import javax.media.jai.JAI;
019: import javax.media.jai.OperationDescriptorImpl;
020: import javax.media.jai.ParameterBlockJAI;
021: import javax.media.jai.RenderableOp;
022: import javax.media.jai.RenderedOp;
023: import javax.media.jai.registry.RenderableRegistryMode;
024: import javax.media.jai.registry.RenderedRegistryMode;
025:
026: /**
027: * An <code>OperationDescriptor</code> describing the "Clamp" operation.
028: *
029: * <p> The Clamp operation takes one rendered or renderable source
030: * image, and sets all the pixels whose value is below a "low" value
031: * to that low value and all the pixels whose value is above a "high"
032: * value to that high value. The pixels whose value is between the
033: * "low" value and the "high" value are left unchanged.
034: *
035: * <p> A different set of "low" and "high" values may be applied to each
036: * band of the source image, or the same set of "low" and "high" values
037: * may be applied to all bands of the source. If the number of "low" and
038: * "high" values supplied is less than the number of bands of the source,
039: * then the values from entry 0 are applied to all the bands. Each "low"
040: * value must be less than or equal to its corresponding "high" value.
041: *
042: * <p> The destination pixel values are defined by the pseudocode:
043: * <pre>
044: * lowVal = (low.length < dstNumBands) ?
045: * low[0] : low[b];
046: * highVal = (high.length < dstNumBands) ?
047: * high[0] : high[b];
048: *
049: * if (src[x][y][b] < lowVal) {
050: * dst[x][y][b] = lowVal;
051: * } else if (src[x][y][b] > highVal) {
052: * dst[x][y][b] = highVal;
053: * } else {
054: * dst[x][y][b] = src[x][y][b];
055: * }
056: * </pre>
057: *
058: * <p><table border=1>
059: * <caption>Resource List</caption>
060: * <tr><th>Name</th> <th>Value</th></tr>
061: * <tr><td>GlobalName</td> <td>Clamp</td></tr>
062: * <tr><td>LocalName</td> <td>Clamp</td></tr>
063: * <tr><td>Vendor</td> <td>com.sun.media.jai</td></tr>
064: * <tr><td>Description</td> <td>Clamps the pixel values of an image
065: * to a specified range.</td></tr>
066: * <tr><td>DocURL</td> <td>http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ClampDescriptor.html</td></tr>
067: * <tr><td>Version</td> <td>1.0</td></tr>
068: * <tr><td>arg0Desc</td> <td>The lower boundary for each band.</td></tr>
069: * <tr><td>arg1Desc</td> <td>The upper boundary for each band.</td></tr>
070: * </table></p>
071: *
072: * <p><table border=1>
073: * <caption>Parameter List</caption>
074: * <tr><th>Name</th> <th>Class Type</th>
075: * <th>Default Value</th></tr>
076: * <tr><td>low</td> <td>double[]</td>
077: * <td>{0.0}</td>
078: * <tr><td>high</td> <td>double[]</td>
079: * <td>{255.0}</td>
080: * </table></p>
081: *
082: * @see javax.media.jai.OperationDescriptor
083: */
084: public class ClampDescriptor extends OperationDescriptorImpl {
085:
086: /**
087: * The resource strings that provide the general documentation
088: * and specify the parameter list for this operation.
089: */
090: private static final String[][] resources = {
091: { "GlobalName", "Clamp" },
092: { "LocalName", "Clamp" },
093: { "Vendor", "com.sun.media.jai" },
094: { "Description", JaiI18N.getString("ClampDescriptor0") },
095: {
096: "DocURL",
097: "http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/ClampDescriptor.html" },
098: { "Version", JaiI18N.getString("DescriptorVersion") },
099: { "arg0Desc", JaiI18N.getString("ClampDescriptor1") },
100: { "arg1Desc", JaiI18N.getString("ClampDescriptor2") } };
101:
102: /** The parameter class list for this operation. */
103: private static final Class[] paramClasses = { double[].class,
104: double[].class };
105:
106: /** The parameter name list for this operation. */
107: private static final String[] paramNames = { "low", "high" };
108:
109: /** The parameter default value list for this operation. */
110: private static final Object[] paramDefaults = {
111: new double[] { 0.0 }, new double[] { 255.0 } };
112:
113: /** Constructor. */
114: public ClampDescriptor() {
115: super (resources, 1, paramClasses, paramNames, paramDefaults);
116: }
117:
118: /** Returns <code>true</code> since renderable operation is supported. */
119: public boolean isRenderableSupported() {
120: return true;
121: }
122:
123: /**
124: * Validates the input parameters.
125: *
126: * <p> In addition to the standard checks performed by the
127: * superclass method, this method checks that "low" and "high"
128: * have length at least 1 and that each "low" value is less than
129: * or equal to the corresponding "high" value.
130: */
131: protected boolean validateParameters(ParameterBlock args,
132: StringBuffer msg) {
133: if (!super .validateParameters(args, msg)) {
134: return false;
135: }
136:
137: double[] low = (double[]) args.getObjectParameter(0);
138: double[] high = (double[]) args.getObjectParameter(1);
139:
140: if (low.length < 1 || high.length < 1) {
141: msg.append(getName() + " "
142: + JaiI18N.getString("ClampDescriptor3"));
143: return false;
144: }
145:
146: int length = Math.min(low.length, high.length);
147: for (int i = 0; i < length; i++) {
148: if (low[i] > high[i]) {
149: msg.append(getName() + " "
150: + JaiI18N.getString("ClampDescriptor4"));
151: return false;
152: }
153: }
154:
155: return true;
156: }
157:
158: /**
159: * Clamps the pixel values of an image to a specified range.
160: *
161: * <p>Creates a <code>ParameterBlockJAI</code> from all
162: * supplied arguments except <code>hints</code> and invokes
163: * {@link JAI#create(String,ParameterBlock,RenderingHints)}.
164: *
165: * @see JAI
166: * @see ParameterBlockJAI
167: * @see RenderedOp
168: *
169: * @param source0 <code>RenderedImage</code> source 0.
170: * @param low The lower boundary for each band.
171: * May be <code>null</code>.
172: * @param high The upper boundary for each band.
173: * May be <code>null</code>.
174: * @param hints The <code>RenderingHints</code> to use.
175: * May be <code>null</code>.
176: * @return The <code>RenderedOp</code> destination.
177: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
178: */
179: public static RenderedOp create(RenderedImage source0,
180: double[] low, double[] high, RenderingHints hints) {
181: ParameterBlockJAI pb = new ParameterBlockJAI("Clamp",
182: RenderedRegistryMode.MODE_NAME);
183:
184: pb.setSource("source0", source0);
185:
186: pb.setParameter("low", low);
187: pb.setParameter("high", high);
188:
189: return JAI.create("Clamp", pb, hints);
190: }
191:
192: /**
193: * Clamps the pixel values of an image to a specified range.
194: *
195: * <p>Creates a <code>ParameterBlockJAI</code> from all
196: * supplied arguments except <code>hints</code> and invokes
197: * {@link JAI#createRenderable(String,ParameterBlock,RenderingHints)}.
198: *
199: * @see JAI
200: * @see ParameterBlockJAI
201: * @see RenderableOp
202: *
203: * @param source0 <code>RenderableImage</code> source 0.
204: * @param low The lower boundary for each band.
205: * May be <code>null</code>.
206: * @param high The upper boundary for each band.
207: * May be <code>null</code>.
208: * @param hints The <code>RenderingHints</code> to use.
209: * May be <code>null</code>.
210: * @return The <code>RenderableOp</code> destination.
211: * @throws IllegalArgumentException if <code>source0</code> is <code>null</code>.
212: */
213: public static RenderableOp createRenderable(
214: RenderableImage source0, double[] low, double[] high,
215: RenderingHints hints) {
216: ParameterBlockJAI pb = new ParameterBlockJAI("Clamp",
217: RenderableRegistryMode.MODE_NAME);
218:
219: pb.setSource("source0", source0);
220:
221: pb.setParameter("low", low);
222: pb.setParameter("high", high);
223:
224: return JAI.createRenderable("Clamp", pb, hints);
225: }
226: }
|