001 /*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2013
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas
009 *
010 * All Rights Reserved
011 *
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.
014 *
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 *
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023 * GNU Lesser Public License for more details.
024 *
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program. If not, see http://www.gnu.org/licenses.
027 */
028
029 package edu.wisc.ssec.mcidasv.data.hydra;
030
031 import ucar.visad.display.GridDisplayable;
032 import ucar.visad.display.DisplayableData;
033 import ucar.visad.display.ScalarMapSet;
034
035 import ucar.unidata.data.grid.GridUtil;
036
037 import ucar.unidata.util.Misc;
038
039 import visad.*;
040
041 import visad.bom.ImageRendererJ3D;
042 import visad.java3d.DefaultRendererJ3D;
043
044 import visad.java2d.*;
045 import visad.java2d.DefaultRendererJ2D;
046
047 import visad.java2d.DisplayRendererJ2D;
048
049
050 import java.rmi.RemoteException;
051
052
053
054 /**
055 * Provides support for a Displayable that needs a map to
056 * (Display.Red,Display.Green,Display.Blue)
057 *
058 * @author IDV development team
059 * @version $Revision$
060 */
061 public class ImageRGBDisplayable extends DisplayableData implements GridDisplayable {
062
063
064 /** color ScalarMaps */
065 private volatile ScalarMap[] colorMaps = { null, null, null };
066
067 /** color MathType */
068 private volatile RealTupleType colorTupleType;
069
070 /** color palette */
071 private float[][] colorPalette;
072
073 /** What do we map with */
074 private DisplayRealType mapType = Display.RGB;
075
076 /** flag for whether we use Alpha channel or not */
077 private boolean doAlpha = false;
078
079 private static int uniqueID = 0;
080
081
082 /**
083 * Constructs from a name for the Displayable and the type of the
084 * RGB parameter.
085 *
086 * @param name The name for the displayable.
087 * @throws VisADException VisAD failure.
088 * @throws RemoteException Java RMI failure.
089 */
090 public ImageRGBDisplayable(String name)
091 throws VisADException, RemoteException {
092 this(name, false);
093 }
094
095
096 /**
097 * Constructs from a name for the Displayable and the type of the
098 * RGB parameter.
099 *
100 * @param name The name for the displayable.
101 * @param doAlpha true to map to RGBA
102 * @throws VisADException VisAD failure.
103 * @throws RemoteException Java RMI failure.
104 */
105 public ImageRGBDisplayable(String name, boolean doAlpha)
106 throws VisADException, RemoteException {
107 this(name, BaseColorControl.initTableGreyWedge(new float[(doAlpha)
108 ? 4
109 : 3][255]), doAlpha);
110 }
111
112 /**
113 * Constructs from a name for the Displayable and the type of the
114 * RGB parameter.
115 *
116 * @param name The name for the displayable.
117 * @param colorPalette The color palette
118 * @param doAlpha true to map to RGBA
119 * @throws VisADException VisAD failure.
120 * @throws RemoteException Java RMI failure.
121 */
122 public ImageRGBDisplayable(String name, float[][] colorPalette,
123 boolean doAlpha)
124 throws VisADException, RemoteException {
125 this(name, colorPalette, doAlpha, null);
126 }
127
128
129 /**
130 * Constructs from another instance. The following attributes are set from
131 * the other instance: color palette, the color RealType.
132 * @param that The other instance.
133 * @throws VisADException VisAD failure.
134 * @throws RemoteException Java RMI failure.
135 */
136 protected ImageRGBDisplayable(ImageRGBDisplayable that)
137 throws VisADException, RemoteException {
138
139 super(that);
140 this.doAlpha = that.doAlpha;
141 colorTupleType = that.colorTupleType;
142 colorPalette = Set.copyFloats(that.colorPalette);
143 if (colorTupleType != null) {
144 setColorMaps();
145 }
146 }
147
148 public ImageRGBDisplayable(String name, float[][] colorPalette, boolean doAlpha, FieldImpl field)
149 throws VisADException, RemoteException {
150 super(name);
151 this.doAlpha = doAlpha;
152 if (doAlpha) {
153 mapType = Display.RGBA;
154 colorMaps = new ScalarMap[] { null, null, null, null };
155 }
156
157 addConstantMaps(new ConstantMap[] {
158 new ConstantMap(GraphicsModeControl.SUM_COLOR_MODE,
159 Display.ColorMode),
160 new ConstantMap(1.0, Display.MissingTransparent) });
161
162
163 if (field != null) {
164 TupleType tt = GridUtil.getParamType(field);
165 RealTupleType ffldType = new RealTupleType(tt.getRealComponents());
166
167 if ((getColorTupleType() == null)
168 || !ffldType.equals(getColorTupleType())) {
169 setColorTupleType(ffldType);
170 }
171 }
172 }
173
174
175
176 /**
177 * Set the data into the Displayable; set RGB Type
178 *
179 *
180 * @param field an image or sequence of images
181 * @exception VisADException from construction of VisAd objects
182 * @exception RemoteException from construction of VisAD objects
183 */
184 public void loadData(FieldImpl field)
185 throws VisADException, RemoteException {
186 setData(field);
187 }
188
189
190 /**
191 * Get the RealTupleType of the RGB parameter.
192 * @return The RealTupleType of the RGB parameters.
193 * May be <code>null</code>.
194 */
195 public RealTupleType getColorTupleType() {
196 return colorTupleType;
197 }
198
199 /**
200 * Sets the RealTupleType of the RGB parameter.
201 * @param realTupleType The RealTupleType of the RGB parameters. May
202 * not be <code>null</code>.
203 * @throws VisADException VisAD failure.
204 * @throws RemoteException Java RMI failure.
205 */
206 protected void setColorTupleType(RealTupleType realTupleType)
207 throws RemoteException, VisADException {
208
209 if ( !realTupleType.equals(colorTupleType)) {
210 RealTupleType oldValue = colorTupleType;
211 colorTupleType = realTupleType;
212 setColorMaps();
213 }
214 }
215
216
217 /**
218 * Returns the RealTupleType of the RGB parameter.
219 * @return The RealTupleType of the color parameter. May
220 * be <code>null</code>.
221 * @deprecated use getColorTupleType()
222 */
223 public RealTupleType getRGBRealTupleType() {
224 return colorTupleType;
225 }
226
227
228 /**
229 * Sets the set of ScalarMap-s of this instance. The ScalarMap-s of
230 * this instance will be added to the set before the SCALAR_MAP_SET
231 * property is set. This method fires a PropertyChangeEvent for
232 * SCALAR_MAP_SET with <code>null</code> for the old value and the new
233 * set of ScalarMap-s for the new Value. Intermediate subclasses that
234 * have their own ScalarMap-s should override this method and invoke
235 * <code>super.setScalarMaps(ScalarMapSet)</code>.
236 * @param maps The set of ScalarMap-s to be added.
237 * @throws BadMappingException The RealType of the color parameter
238 * has not been set or its ScalarMap is alread in
239 * the set.
240 */
241 protected void setScalarMaps(ScalarMapSet maps)
242 throws BadMappingException {
243
244 if (colorMaps[0] == null) {
245 throw new BadMappingException(getClass().getName()
246 + ".setScalarMaps(ScalarMapSet): "
247 + "Color not yet set");
248 }
249
250 for (int i = 0; i < colorMaps.length; i++) {
251 maps.add(colorMaps[i]);
252 }
253 super.setScalarMapSet(maps);
254 }
255
256 /**
257 * Set the alpha. Unused.
258 *
259 * @param alpha alpha
260 *
261 * @throws RemoteException On badness
262 * @throws VisADException On badness
263 */
264 public void setAlpha(float alpha) throws RemoteException, VisADException {
265 addConstantMaps(new ConstantMap[] {
266 new ConstantMap(alpha, Display.Alpha) });
267 }
268
269 /**
270 * creates the ScalarMaps for color for this Displayable.
271 *
272 * @throws VisADException VisAD failure.
273 * @throws RemoteException Java RMI failure.
274 */
275 private void setColorMaps() throws RemoteException, VisADException {
276
277 ScalarMapSet set = new ScalarMapSet();
278 for (int i = 0; i < colorMaps.length; i++) {
279 colorMaps[i] =
280 new ScalarMap((RealType) colorTupleType.getComponent(i),
281 mapType);
282 /* TODO: maybe allow user to set range. If so, just copy
283 logic from RGBDisplayable */
284 //-TDR colorMaps[i].setRange(0, 255);
285 set.add(colorMaps[i]);
286 final int colorMapIndex = i;
287 colorMaps[i].addScalarMapListener(new ScalarMapListener() {
288 public void controlChanged(ScalarMapControlEvent event)
289 throws RemoteException, VisADException {
290 int id = event.getId();
291 if ((id == event.CONTROL_ADDED)
292 || (id == event.CONTROL_REPLACED)) {
293 setColorsInControls(colorPalette, colorMapIndex);
294 }
295 }
296
297 public void mapChanged(ScalarMapEvent event)
298 throws RemoteException, VisADException {
299 }
300 });
301 }
302
303 setScalarMapSet(set);
304 setColorsInControls(colorPalette);
305 }
306
307 /**
308 * Set the display.
309 *
310 * @param display display to set this into
311 *
312 * @throws DisplayException Display type exception
313 * @throws RemoteException Java RMI error
314 * @throws VisADException problem creating VisAD object
315 */
316 public void setDisplay(LocalDisplay display)
317 throws DisplayException, VisADException, RemoteException {
318 super.setDisplay(display);
319 setColorsInControls(colorPalette);
320 }
321
322 /**
323 * This method sets the color palette
324 * according to the color table in argument;
325 * pair this method with setRange(lo,high) to get
326 * a fixed association of color table and range of values.
327 *
328 * @param colorPalette the color table or color-alpha table desired
329 * @throws VisADException if a core VisAD failure occurs.
330 * @throws RemoteException if a Java RMI failure occurs.
331 */
332 public void setColorPalette(float[][] colorPalette)
333 throws RemoteException, VisADException {
334
335 setColorsInControls(colorPalette);
336 this.colorPalette = colorPalette;
337 }
338
339 /**
340 * Return the current color palette in this Displayable
341 *
342 * @return a color table float[3][len] or color-alpha table float[4][len]
343 */
344 public float[][] getColorPalette() {
345 return colorPalette;
346 }
347
348
349 /**
350 * Set colors for the controls of all color maps.
351 *
352 * @param colorPalette The 3xN color palette array
353 *
354 * @throws RemoteException Java RMI error
355 * @throws VisADException problem creating VisAD object
356 */
357 private void setColorsInControls(float[][] colorPalette)
358 throws RemoteException, VisADException {
359
360 for (int i = 0; i < colorMaps.length; i++) {
361 setColorsInControls(colorPalette, i);
362 }
363 }
364
365
366
367
368 /**
369 * Set colors for the control defined by the given colorMapIndex (0,1 or 2).
370 *
371 * @param colorPalette The 3xN color palette array
372 * @param colorMapIndex Which of the color maps are we setting the color of.
373 *
374 * @throws RemoteException Java RMI error
375 * @throws VisADException problem creating VisAD object
376 */
377 private void setColorsInControls(float[][] colorPalette,
378 int colorMapIndex)
379 throws RemoteException, VisADException {
380 if (colorPalette == null) {
381 return;
382 }
383
384
385 if (colorMaps[colorMapIndex] == null) {
386 return;
387 }
388
389 BaseColorControl bcc =
390 (BaseColorControl) colorMaps[colorMapIndex].getControl();
391
392 if (bcc != null) {
393 float[][] table =
394 new float[colorMaps.length][colorPalette[0].length];
395 table[colorMapIndex] = colorPalette[colorMapIndex];
396 bcc.setTable(table);
397 }
398 }
399
400 protected DataRenderer getDataRenderer() throws VisADException {
401
402 ImageRendererJ3D myRenderer = new ImageRendererJ3D();
403 return myRenderer;
404
405 }
406
407
408 /**
409 * Set whether this GridDisplayable should have the data colored
410 * by another parameter. This implementation is a no-op.
411 *
412 * @param yesno true if colored by another
413 */
414 public void setColoredByAnother(boolean yesno) {}
415
416 }