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 }