001: /*
002: * @(#) $Header: /cvs/jai-operators/src/main/ca/forklabs/media/jai/opimage/ImageFunction3DOpImage.java,v 1.2 2007/08/16 21:24:18 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.opimage;
022:
023: import java.awt.RenderingHints;
024: import java.awt.image.DataBuffer;
025: import java.awt.image.DataBufferDouble;
026: import java.awt.image.DataBufferFloat;
027: import java.awt.image.RenderedImage;
028: import java.awt.image.SampleModel;
029: import java.util.Collection;
030: import javax.media.jai.CollectionImage;
031: import javax.media.jai.ImageLayout;
032: import com.sun.media.jai.opimage.RIFUtil;
033: import ca.forklabs.media.jai.ImageFunction3D;
034: import ca.forklabs.media.jai.RasterAdapter;
035: import ca.forklabs.media.jai.SimpleCollectionImage;
036:
037: /**
038: * Class {@code ImageFunction3DOpImage} is the {@link CollectionImage} for
039: * operator <em>imagefunction3d</em>.
040: *
041: * @author <a href="mailto:forklabs at dev.java.net?subject=ca.forklabs.media.jai.opimage.ImageFunction3DOpImage">Daniel Léonard</a>
042: * @version $Revision: 1.2 $
043: */
044: public class ImageFunction3DOpImage extends SimpleCollectionImage {
045:
046: //---------------------------
047: // Class variables
048: //---------------------------
049:
050: // exceptionnally, class variables are at the end
051:
052: //---------------------------
053: // Constructors
054: //---------------------------
055:
056: /**
057: * Constructor.
058: * @param function the functional description.
059: * @param width the width of the image.
060: * @param height the height of the image.
061: * @param depth the depth of the image.
062: * @param hints rendering hints.
063: */
064: public ImageFunction3DOpImage(ImageFunction3D function, int width,
065: int height, int depth, RenderingHints hints) {
066: this .create(function, width, height, depth, hints);
067: }
068:
069: //---------------------------
070: // Instance methods
071: //---------------------------
072:
073: /**
074: * Gets the data type. The default data type is {@code float}. If a sample
075: * model is provided in the rendering hints, its data type will be respected,
076: * provided it is {@code float} or {@code double}.
077: * @param hints rendering hints.
078: * @return the data type of the image.
079: */
080: protected int getDataType(RenderingHints hints) {
081: int type = DataBuffer.TYPE_FLOAT;
082:
083: ImageLayout layout = RIFUtil.getImageLayoutHint(hints);
084: if ((null != layout)
085: && layout.isValid(ImageLayout.SAMPLE_MODEL_MASK)) {
086: SampleModel model = layout.getSampleModel(null);
087: type = model.getDataType();
088: }
089:
090: return type;
091: }
092:
093: /**
094: * Really creates the image.
095: * @param function the functional description.
096: * @param width the width of the image.
097: * @param height the height of the image.
098: * @param depth the depth of the image.
099: * @param specialization the pixel specialization.
100: * @param <T> the type of data, either <code>float[]</code> or
101: * <code>double[]</code>.
102: */
103: @SuppressWarnings({"hiding","unchecked"})
104: protected <T> void create(ImageFunction3D function, int width,
105: int height, int depth, PixelSpecialization<T> specialization) {
106: Collection sinks = this .getImages();
107:
108: boolean is_complex = function.isComplex();
109: int len = width * height;
110: int bands = function.getNumBands();
111: if (is_complex) {
112: bands *= 2;
113: }
114:
115: for (int d = 0; d < depth; d++) {
116: T[] data = specialization.newDataArray(bands, len);
117:
118: for (int b = 0; b < bands; b += (is_complex) ? 2 : 1) {
119: T real = (is_complex) ? data[b] : data[b];
120: T imag = (is_complex) ? data[b + 1] : null;
121: specialization.generateBand(function, b, d, width,
122: height, depth, real, imag);
123: }
124:
125: DataBuffer buffer = specialization.newDataBuffer(data, len);
126:
127: RenderedImage sink = RasterAdapter.buildImage(buffer,
128: width, height);
129: sinks.add(sink);
130: }
131: }
132:
133: /**
134: * Creates a float image.
135: * @param function the functional description.
136: * @param width the width of the image.
137: * @param height the height of the image.
138: * @param depth the depth of the image.
139: */
140: protected void createFloat(ImageFunction3D function, int width,
141: int height, int depth) {
142: PixelSpecialization<float[]> specialization = ImageFunction3DOpImage.FLOAT_SPECIALIZATION;
143: this .create(function, width, height, depth, specialization);
144: }
145:
146: /**
147: * Creates a double image.
148: * @param function the functional description.
149: * @param width the width of the image.
150: * @param height the height of the image.
151: * @param depth the depth of the image.
152: */
153: protected void createDouble(ImageFunction3D function, int width,
154: int height, int depth) {
155: PixelSpecialization<double[]> specialization = ImageFunction3DOpImage.DOUBLE_SPECIALIZATION;
156: this .create(function, width, height, depth, specialization);
157: }
158:
159: /**
160: * Creates the image.
161: * @param function the functional description.
162: * @param width the width of the image.
163: * @param height the height of the image.
164: * @param depth the depth of the image.
165: * @param hints rendering hints.
166: */
167: protected void create(ImageFunction3D function, int width,
168: int height, int depth, RenderingHints hints) {
169: int data_type = this .getDataType(hints);
170: switch (data_type) {
171: case DataBuffer.TYPE_DOUBLE:
172: this .createDouble(function, width, height, depth);
173: break;
174: default:
175: this .createFloat(function, width, height, depth);
176: break;
177: }
178: }
179:
180: //---------------------------
181: // Inner classes
182: //---------------------------
183:
184: /**
185: * Class {@code PixelSpecialization} specializes pixel manipulation on the
186: * array type.
187: *
188: * @param <T> the array type (such as {@code float[]} or
189: * {@code double[]}).
190: *
191: * @author <a href="mailto:forklabs at dev.java.net?subject=ca.forklabs.media.jai.operator.ImageFunction3DOpImageOpImage$PixelSpecialization">Daniel Léonard</a>
192: * @version $Revision: 1.2 $
193: */
194: protected static abstract class PixelSpecialization<T> {
195:
196: /**
197: * Creates a new data array to hold all the pixels of one image in the collection.
198: * @param bands the number of bands.
199: * @param len the number of pixels.
200: * @return a new data array.
201: */
202: public abstract T[] newDataArray(int bands, int len);
203:
204: /**
205: * Generates the given band.
206: * @param function the functional description.
207: * @param band the band of the image.
208: * @param slice the image position in the collection.
209: * @param width the width of the image.
210: * @param height the height of the image.
211: * @param depth the number of images in the collection.
212: * @param real placeholder array for the real values.
213: * @param imag placeholder array for the imaginary values,
214: * {@code null} if the image is NOT complex.
215: */
216: public abstract void generateBand(ImageFunction3D function,
217: int band, int slice, int width, int height, int depth,
218: T real, T imag);
219:
220: /**
221: * Creates a new data buffer to hold the data array.
222: * @param data the pixel data.
223: * @param size the number of pixels in the image.
224: * @return a new data buffer.
225: */
226: public abstract DataBuffer newDataBuffer(T[] data, int size);
227:
228: }
229:
230: //---------------------------
231: // Class variables
232: //---------------------------
233:
234: /** Specialization for the <em>float</em> data type. */
235: protected static final PixelSpecialization<float[]> FLOAT_SPECIALIZATION = new PixelSpecialization<float[]>() {
236:
237: @Override
238: public float[][] newDataArray(int bands, int len) {
239: float[][] data = new float[bands][len];
240: return data;
241: }
242:
243: @Override
244: public void generateBand(ImageFunction3D function, int band,
245: int slice, int width, int height, int depth,
246: float[] real, float[] imag) {
247: function.getBand(band, slice, width, height, depth, real,
248: imag);
249: }
250:
251: @Override
252: public DataBuffer newDataBuffer(float[][] data, int size) {
253: DataBuffer buffer = new DataBufferFloat(data, size);
254: return buffer;
255: }
256:
257: };
258:
259: /** Specialization for the <em>double</em> data type. */
260: protected static final PixelSpecialization<double[]> DOUBLE_SPECIALIZATION = new PixelSpecialization<double[]>() {
261:
262: @Override
263: public double[][] newDataArray(int bands, int len) {
264: double[][] data = new double[bands][len];
265: return data;
266: }
267:
268: @Override
269: public void generateBand(ImageFunction3D function, int band,
270: int slice, int width, int height, int depth,
271: double[] real, double[] imag) {
272: function.getBand(band, slice, width, height, depth, real,
273: imag);
274: }
275:
276: @Override
277: public DataBuffer newDataBuffer(double[][] data, int size) {
278: DataBuffer buffer = new DataBufferDouble(data, size);
279: return buffer;
280: }
281:
282: };
283:
284: }
285:
286: /*
287: * $Log: ImageFunction3DOpImage.java,v $
288: * Revision 1.2 2007/08/16 21:24:18 forklabs
289: * Removed whitespace in import statements.
290: *
291: * Revision 1.1 2007/07/05 18:30:37 forklabs
292: * Operator imagefunction3d.
293: *
294: */
|