001: /*
002: * @(#) $Header: /cvs/jai-operators/src/main/ca/forklabs/media/jai/operator/SpectralFilterDescriptor.java,v 1.1 2007/07/17 16:34:35 forklabs Exp $
003: *
004: * Copyright (C) 2007 Forklabs Daniel Léonard
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: */
020:
021: package ca.forklabs.media.jai.operator;
022:
023: import java.awt.RenderingHints;
024: import java.awt.image.RenderedImage;
025: import java.awt.image.renderable.RenderableImage;
026: import java.util.Collection;
027: import javax.media.jai.CollectionImage;
028: import javax.media.jai.JAI;
029: import javax.media.jai.OperationDescriptor;
030: import javax.media.jai.ParameterBlockJAI;
031: import javax.media.jai.ParameterListDescriptor;
032: import javax.media.jai.RenderableOp;
033: import javax.media.jai.RenderedOp;
034: import javax.media.jai.registry.CollectionRegistryMode;
035: import javax.media.jai.registry.RenderableRegistryMode;
036: import javax.media.jai.registry.RenderedRegistryMode;
037: import ca.forklabs.media.jai.CollectionDescriptor;
038: import ca.forklabs.media.jai.FormatDataType;
039: import ca.forklabs.media.jai.SpectralFilter2D;
040: import ca.forklabs.media.jai.SpectralFilter3D;
041:
042: /**
043: * Class {@code SpectralFilterDescriptor} is an {@link OperationDescriptor}
044: * describing the <em>spectralfilter</em> operation. This composite
045: * operation consists of these four steps :
046: * <blockquote>
047: * format -> fft -> filter -> ifft ->
048: * </blockquote>
049: * The <em>spectralfilter</em> operation takes two parameters, the filter
050: * and the data type for the format operation :
051: * <dl>
052: * <dt>filter</dt>
053: * <dd>This argument will provide the filter image to multiply to the Fourier
054: * transform.</dd>
055: * <dt>data type</dt>
056: * <dd>This argument is the type for the format operation. Data format can be
057: * found in enum {@link FormatDataType}. The default value is
058: * {@link FormatDataType#FLOAT}.</dd>
059: * </dl>
060: * <p>
061: * Here is a description of each step :
062: * <dl>
063: * <dt>format</dt>
064: * <dd>The format step change the type of the image pixel. Its behaviour can
065: * be controlled with the data type parameter.</dd>
066: * <dt>fft</dt>
067: * <dd>This step calculates the Fourier Transform, using no scaling.</dd>
068: * <dt>filter</dt>
069: * <dd>The filter image will be generated and multiplied to the Fourier
070: * transform.</dd>
071: * <dt>ifft</dt>
072: * <dd>This step calculates the Inverse Fourier Transform, using the
073: * dimension scaling.</dd>
074: * </dl>
075: * <p>
076: *
077: * <table border=1>
078: * <caption>Resource List</caption>
079: * <tr><th>Name</th> <th>Value</th></tr>
080: * <tr><td>GlobalName</td> <td>SpectralFilter</td></tr>
081: * <tr><td>LocalName</td> <td>SpectralFilter</td></tr>
082: * <tr><td>Vendor</td> <td>ca.umontreal.iro.image.arcticice</td></tr>
083: * <tr><td>Description</td> <td>Spectral Filter</td></tr>
084: * <tr><td>DocURL</td> <td>n/a</td></tr>
085: * <tr><td>Version</td> <td>$Version$</td></tr>
086: * <tr><td>Arg0Desct</td> <td>The spectral filter</td></tr>
087: * <tr><td>Arg1Desct</td> <td>The data type for the format operation</td></tr>
088: * </table>
089: *
090: * <table border=1>
091: * <caption>Parameter List for the <em>rendered</em> and <em>renderable</em> modes</caption>
092: * <tr><th>Name</th> <th>Class Type</th> <th>Default Value</th></tr>
093: * <tr><td>filter</td> <td>SpectralFilter2D</td> <td>NO_PARAMETER_DEFAULT</td>
094: * <tr><td>type</td> <td>FormatDataType</td> <td>FormatDataType.FLOAT</td>
095: * </table>
096: * <table border=1>
097: * <caption>Parameter List for the <em>collection</em> mode</caption>
098: * <tr><th>Name</th> <th>Class Type</th> <th>Default Value</th></tr>
099: * <tr><td>filter</td> <td>SpectralFilter3D</td> <td>NO_PARAMETER_DEFAULT</td>
100: * <tr><td>type</td> <td>FormatDataType</td> <td>FormatDataType.FLOAT</td>
101: * </table>
102: *
103: * @author <a href="mailto:daniel.leonard at umontreal.ca?subject=ca.umontreal.iro.image.arcticice.media.jai.operator.SpectralDescriptor">Daniel Léonard</a>
104: * @version $Revision: 1.1 $
105: */
106: public class SpectralFilterDescriptor extends CollectionDescriptor {
107:
108: //---------------------------
109: // Class variables
110: //---------------------------
111:
112: /** <em>serialVersionUID</em>. */
113: private static final long serialVersionUID = -3138118927177422248L;
114:
115: /** The name of this operator. */
116: @SuppressWarnings("nls")
117: public static final String NAME = "SpectralFilter";
118:
119: /** The name of the filter parameter. */
120: @SuppressWarnings("nls")
121: public static final String FILTER_PARAMETER_NAME = "filter";
122: /** The name of the initial format type parameter. */
123: @SuppressWarnings("nls")
124: public static final String TYPE_PARAMETER_NAME = "type";
125:
126: /** The index in the parameter block of the filter parameter. */
127: public static final int FILTER_PARAMETER_INDEX = 0;
128: /** The index in the parameter block of the data type parameter. */
129: public static final int TYPE_PARAMETER_INDEX = 1;
130:
131: /**
132: * The resource strings that provide the general documentation and specify
133: * the parameter list for this operation.
134: */
135: @SuppressWarnings("nls")
136: private static final String[][] RESOURCES = {
137: { "GlobalName", SpectralFilterDescriptor.NAME, },
138: { "LocalName", SpectralFilterDescriptor.NAME, },
139: { "Vendor", "ca.umontreal.iro.image.arcticice", },
140: { "Description", SpectralFilterDescriptor.getDescription(), },
141: { "DocURL", "n/a", },
142: { "Version", "$Version$", },
143: { "arg0Desc",
144: SpectralFilterDescriptor.getArg0Description(), },
145: { "arg1Desc",
146: SpectralFilterDescriptor.getArg1Description(), }, };
147:
148: /** The supported modes. */
149: private static final String[] SUPPORTED_MODES = {
150: RenderedRegistryMode.MODE_NAME,
151: RenderableRegistryMode.MODE_NAME,
152: CollectionRegistryMode.MODE_NAME, };
153:
154: /** The name of the source, use default. */
155: private static final String[] SOURCE_NAMES = null;
156:
157: /** The type of source for each mode. */
158: private static final Class<?>[][] SOURCE_CLASSES = new Class<?>[][] {
159: { Collection.class, }, { Collection.class, },
160: { Collection.class, }, };
161:
162: protected static class SpectralHomomorphicParameterListDescriptor
163: extends CollectionDescriptor.EmptyParameterListDescriptor {
164:
165: /**
166: * Gets the number of parameters for this operator.
167: * @return always <em>2</em>.
168: */
169: @Override
170: public int getNumParameters() {
171: int num_parameters = 2;
172: return num_parameters;
173: }
174:
175: /**
176: * {@inheritDoc}
177: */
178: @Override
179: @SuppressWarnings({"static-access","synthetic-access"})
180: public Object getParamDefaultValue(String name) {
181: int index;
182: if (SpectralFilterDescriptor.FILTER_PARAMETER_NAME
183: .equals(name)) {
184: index = SpectralFilterDescriptor.FILTER_PARAMETER_INDEX;
185: } else if (SpectralFilterDescriptor.TYPE_PARAMETER_NAME
186: .equals(name)) {
187: index = SpectralFilterDescriptor.TYPE_PARAMETER_INDEX;
188: } else {
189: // this call throws an exception
190: return super .getParamDefaultValue(name);
191: }
192:
193: Object[] values = this .getParamDefaults();
194: Object value = values[index];
195: return value;
196: }
197:
198: /**
199: * Gets the default values.
200: * @return no default value for the filter, type float for the data
201: * type.
202: */
203: @Override
204: public Object[] getParamDefaults() {
205: Object[] defaults = new Object[] {
206: // TODO : make a default filter with all 1s for real values and all 0s for imaginary values - watch for type SpectralFilter2D and SpectralFilter3D
207: OperationDescriptor.NO_PARAMETER_DEFAULT,
208: FormatDataType.FLOAT, };
209: return defaults;
210: }
211:
212: /**
213: * {@inheritDoc}
214: */
215: @Override
216: public String[] getParamNames() {
217: String[] names = {
218: SpectralFilterDescriptor.FILTER_PARAMETER_NAME,
219: SpectralFilterDescriptor.TYPE_PARAMETER_NAME, };
220: return names;
221: }
222:
223: /**
224: * Determines if the value is valid.
225: * @return {@code true} if the value is not {@code null},
226: * {@code false} otherwise.
227: */
228: @Override
229: public boolean isParameterValueValid(String name, Object value) {
230: // each parameter is an array, check that it is not null
231: // and nothing more
232: boolean is_valid = (null != value);
233: return is_valid;
234: }
235:
236: }
237:
238: /** The parameter list descriptor for the rendered and renderable modes. */
239: private static final ParameterListDescriptor RENDERED_AND_RENDERABLE_PARAMETER_LIST_DESCRIPTOR = new SpectralHomomorphicParameterListDescriptor() {
240:
241: @Override
242: public Class<?>[] getParamClasses() {
243: Class<?>[] clazzes = new Class<?>[] {
244: SpectralFilter2D.class, FormatDataType.class, };
245: return clazzes;
246: }
247:
248: };
249:
250: /** The parameter list descriptor for the collection mode. */
251: private static final ParameterListDescriptor COLLECTION_PARAMETER_LIST_DESCRIPTOR = new SpectralHomomorphicParameterListDescriptor() {
252:
253: @Override
254: public Class<?>[] getParamClasses() {
255: Class<?>[] clazzes = new Class<?>[] {
256: SpectralFilter3D.class, FormatDataType.class, };
257: return clazzes;
258: }
259:
260: };
261:
262: /** Description of the parameters. */
263: private static final ParameterListDescriptor[] PARAMETER_LIST_DESCRIPTORS = new ParameterListDescriptor[] {
264: SpectralFilterDescriptor.RENDERED_AND_RENDERABLE_PARAMETER_LIST_DESCRIPTOR,
265: SpectralFilterDescriptor.RENDERED_AND_RENDERABLE_PARAMETER_LIST_DESCRIPTOR,
266: SpectralFilterDescriptor.COLLECTION_PARAMETER_LIST_DESCRIPTOR, };
267:
268: //---------------------------
269: // Constructor
270: //---------------------------
271:
272: /**
273: * Constructor.
274: */
275: public SpectralFilterDescriptor() {
276: super (RESOURCES, SUPPORTED_MODES, SOURCE_NAMES, SOURCE_CLASSES,
277: PARAMETER_LIST_DESCRIPTORS);
278: }
279:
280: //---------------------------
281: // Class methods
282: //---------------------------
283:
284: /**
285: * Creates and fills a new parameter block.
286: * @param mode the rendering mode (usually rendered or renderable).
287: * @param source the source image.
288: * @param filter the filter
289: * @param type the data type for the format operation.
290: * @return a new parameter block.
291: */
292: public static ParameterBlockJAI createParameterBlock(String mode,
293: Object source, SpectralFilter2D filter, FormatDataType type) {
294: String name = SpectralFilterDescriptor.NAME;
295: ParameterBlockJAI pb = new ParameterBlockJAI(name, mode);
296: pb.addSource(source);
297: pb.setParameter(SpectralFilterDescriptor.FILTER_PARAMETER_NAME,
298: filter);
299: pb.setParameter(SpectralFilterDescriptor.TYPE_PARAMETER_NAME,
300: type);
301: return pb;
302: }
303:
304: /**
305: * Creates and fills a new parameter block.
306: * @param mode the rendering mode (usually collection).
307: * @param source the source image.
308: * @param filter the filter
309: * @param type the data type for the format operation.
310: * @return a new parameter block.
311: */
312: public static ParameterBlockJAI createParameterBlock(String mode,
313: Object source, SpectralFilter3D filter, FormatDataType type) {
314: String name = SpectralFilterDescriptor.NAME;
315: ParameterBlockJAI pb = new ParameterBlockJAI(name, mode);
316: pb.addSource(source);
317: pb.setParameter(SpectralFilterDescriptor.FILTER_PARAMETER_NAME,
318: filter);
319: pb.setParameter(SpectralFilterDescriptor.TYPE_PARAMETER_NAME,
320: type);
321: return pb;
322: }
323:
324: /**
325: * Creates and fills a new parameter block for the rendered mode.
326: * @param source the source image.
327: * @param filter the filter.
328: * @param type the data type for the format operation.
329: * @return a new parameter block.
330: */
331: public static ParameterBlockJAI createParameterBlock(
332: RenderedImage source, SpectralFilter2D filter,
333: FormatDataType type) {
334: String mode = RenderedRegistryMode.MODE_NAME;
335: ParameterBlockJAI pb = SpectralFilterDescriptor
336: .createParameterBlock(mode, source, filter, type);
337: return pb;
338: }
339:
340: /**
341: * Creates and fills a new parameter block for the renderable mode.
342: * @param source the source image.
343: * @param filter the filter.
344: * @param type the data type for the format operation.
345: * @return a new parameter block.
346: */
347: public static ParameterBlockJAI createParameterBlock(
348: RenderableImage source, SpectralFilter2D filter,
349: FormatDataType type) {
350: String mode = RenderedRegistryMode.MODE_NAME;
351: ParameterBlockJAI pb = SpectralFilterDescriptor
352: .createParameterBlock(mode, source, filter, type);
353: return pb;
354: }
355:
356: /**
357: * Creates and fills a new parameter block for the collection mode.
358: * @param source the source image.
359: * @param filter the filter.
360: * @param type the data type for the format operation.
361: * @return a new parameter block.
362: */
363: public static ParameterBlockJAI createParameterBlock(
364: CollectionImage source, SpectralFilter3D filter,
365: FormatDataType type) {
366: String mode = CollectionRegistryMode.MODE_NAME;
367: ParameterBlockJAI pb = SpectralFilterDescriptor
368: .createParameterBlock(mode, source, filter, type);
369: return pb;
370: }
371:
372: /**
373: * Performs the spatial homomorphic filter operation on a rendered image.
374: * @param source the image to enhance.
375: * @param filter the filter.
376: * @param type the data type for the initial format.
377: * @param hints the rendering hints, may be {@code null}.
378: * @return the rendered result image.
379: */
380: public static RenderedOp create(RenderedImage source,
381: SpectralFilter2D filter, FormatDataType type,
382: RenderingHints hints) {
383: String operation = SpectralFilterDescriptor.NAME;
384: ParameterBlockJAI pb = SpectralFilterDescriptor
385: .createParameterBlock(source, filter, type);
386: RenderedOp image = JAI.create(operation, pb, hints);
387: return image;
388: }
389:
390: /**
391: * Performs the spatial homomorphic filter operation on a renderable image.
392: * @param source the image to enhance.
393: * @param filter the filter.
394: * @param type the data type for the initial format.
395: * @param hints the rendering hints, may be {@code null}.
396: * @return the rendered result image.
397: */
398: public static RenderableOp createRenderable(RenderableImage source,
399: SpectralFilter2D filter, FormatDataType type,
400: RenderingHints hints) {
401: String operation = SpectralFilterDescriptor.NAME;
402: ParameterBlockJAI pb = SpectralFilterDescriptor
403: .createParameterBlock(source, filter, type);
404: RenderableOp image = JAI.createRenderable(operation, pb, hints);
405: return image;
406: }
407:
408: /**
409: * Performs the spatial homomorphic filter operation on a rendered image.
410: * @param source the image to enhance.
411: * @param filter the filter.
412: * @param type the data type for the initial format.
413: * @param hints the rendering hints, may be {@code null}.
414: * @return the rendered result image.
415: */
416: public static CollectionImage createCollection(
417: CollectionImage source, SpectralFilter3D filter,
418: FormatDataType type, RenderingHints hints) {
419: String operation = SpectralFilterDescriptor.NAME;
420: ParameterBlockJAI pb = SpectralFilterDescriptor
421: .createParameterBlock(source, filter, type);
422: CollectionImage image = (CollectionImage) JAI.createCollection(
423: operation, pb, hints);
424: return image;
425: }
426:
427: //---------------------------
428: // External resources methods
429: //---------------------------
430:
431: /**
432: * Gets the description of this operation.
433: * @return the description message.
434: */
435: protected static String getDescription() {
436: String key = Resources.SPECTRAL_FILTER_DESCRIPTION;
437: String message = Resources.getLocalizedString(key);
438: return message;
439: }
440:
441: /**
442: * Gets the description for the first argument, spectral filter.
443: * @return the description message.
444: */
445: protected static String getArg0Description() {
446: String key = Resources.SPECTRAL_FILTER_ARG0_DESCRIPTION;
447: String message = Resources.getLocalizedString(key);
448: return message;
449: }
450:
451: /**
452: * Gets the description for the second argument, the format data type.
453: * @return the description message.
454: */
455: protected static String getArg1Description() {
456: String key = Resources.SPECTRAL_FILTER_ARG1_DESCRIPTION;
457: String message = Resources.getLocalizedString(key);
458: return message;
459: }
460:
461: }
462:
463: /*
464: * $Log: SpectralFilterDescriptor.java,v $
465: * Revision 1.1 2007/07/17 16:34:35 forklabs
466: * Operator spectralfilter.
467: *
468: */
|