1 /*
2  * Copyright (C) 1997-2005, R3vis Corporation.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17  * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
18  *
19  * Original Contributor:
20  *   Wes Bethel, R3vis Corporation, Marin County, California
21  * Additional Contributor(s):
22  *
23  * The OpenRM project is located at http://openrm.sourceforge.net/.
24  */
25 /*
26  * $Id: rmvmap.c,v 1.6 2005/02/19 16:22:50 wes Exp $
27  * Version: $Name: OpenRM-1-6-0-2-RC2 $
28  * $Revision: 1.6 $
29  * $Log: rmvmap.c,v $
30  * Revision 1.6  2005/02/19 16:22:50  wes
31  * Distro sync and consolidation.
32  *
33  * Revision 1.5  2005/01/23 17:00:22  wes
34  * Copyright updated to 2005.
35  *
36  * Revision 1.4  2004/03/30 14:13:31  wes
37  * Fixed declarations and man page docs for several routines.
38  *
39  * Revision 1.3  2004/01/16 16:49:50  wes
40  * Updated copyright line for 2004.
41  *
42  * Revision 1.2  2003/02/02 02:07:16  wes
43  * Updated copyright to 2003.
44  *
45  * Revision 1.1.1.1  2003/01/28 02:15:23  wes
46  * Manual rebuild of rm150 repository.
47  *
48  * Revision 1.5  2003/01/16 22:21:17  wes
49  * Updated all source files to reflect new organization of header files:
50  * all header files formerly located in include/rmaux, include/rmi, include/rmv
51  * are now located in include/rm.
52  *
53  * Revision 1.4  2002/04/30 19:36:22  wes
54  * Updated copyright dates.
55  *
56  * Revision 1.3  2001/03/31 17:12:39  wes
57  * v1.4.0-alpha-2 checkin.
58  *
59  * Revision 1.2  2000/04/20 16:29:47  wes
60  * Documentation additions/enhancements, some code rearragement.
61  *
62  * Revision 1.1.1.1  2000/02/28 21:29:40  wes
63  * OpenRM 1.2 Checkin
64  *
65  * Revision 1.1.1.1  2000/02/28 17:18:47  wes
66  * Initial entry - pre-RM120 release, source base for OpenRM 1.2.
67  *
68  */
69 
70 #include <rm/rm.h>
71 #include "rmprivat.h"
72 
73 /* PRIVATE declarations */
74 RMenum private_rmVismapCheckSize (const RMvisMap *v, int indx, char *funcName);
75 
76 /*
77  * ----------------------------------------------------
78  * @Name rmVismapNew
79  @pstart
80  RMvisMap *rmVismapNew (int size)
81  @pend
82 
83  @astart
84  int size - an int that specifyingthe size of the visualization
85     colormap (input).
86  @aend
87 
88  @dstart
89 
90  Creates a new visualization Colormap, returning the handle to the
91  caller. The caller should use rmVismapDelete() when the vismap is no
92  longer needed to free memory.
93 
94  The size of the visualization colormap is dictated by the input
95  parameter. The newly created visualization colormap of length "size"
96  is set to all zeroes.
97 
98  @dend
99  * ----------------------------------------------------
100  */
101 RMvisMap *
rmVismapNew(int size)102 rmVismapNew (int size)
103 {
104     RMvisMap *v = malloc(sizeof(RMvisMap));
105 
106     memset(v, 0, sizeof(RMvisMap));
107     rmVismapSetSize(v, size);
108     return(v);
109 }
110 
111 
112 /*
113  * ----------------------------------------------------
114  * @Name rmVismapDup
115  @pstart
116  RMvisMap * rmVismapDup (const RMvisMap *toDuplicate)
117  @pend
118 
119  @astart
120  const RMvisMap *toDuplicate - a handle to an RMvisMap
121  @aend
122 
123  @dstart
124 
125  Creates a new RMvisMap object that is an exact duplicate of the input
126  RMvisMap object. Returns a handle to the newly created RMvisMap to
127  the caller if successful, or returns NULL upon failure.
128 
129  The caller should use rmVismapDelete() to free the new RMvisMap
130  object when no longer needed.
131 
132  @dend
133  * ----------------------------------------------------
134  */
135 RMvisMap *
rmVismapDup(const RMvisMap * toDuplicate)136 rmVismapDup (const RMvisMap *toDuplicate)
137 {
138     /* create a new vismap, copy contents of an existing one into it */
139     RMvisMap *t = rmVismapNew(rmVismapGetSize(toDuplicate));
140 
141     if (t == NULL)
142     {
143 	rmError("rmVismapDup() error: unable to create a new RMvisMap, possibly due to a malloc error inside rmVismapNew().");
144 	return NULL;
145     }
146 
147     /* we really should do a component-by-component copy, but instead..  */
148     memcpy((void *)t, (void *)toDuplicate, sizeof(RMvisMap));
149 
150     /*
151      * this works for the time being ONLY because we used fixed-size
152      * arrays for the vismap. when we graduate to dynamically-sized
153      * arrays, things will become more complicated and the memcpy
154      * won't work.
155      */
156     return(t);
157 }
158 
159 
160 /*
161  * ----------------------------------------------------
162  * @Name rmVismapDelete
163  @pstart
164  RMenum rmVismapDelete (RMvisMap *toDelete)
165  @pend
166 
167  @astart
168  RMvisMap *toDelete - a handle to an RMvisMap that will be deleted
169  @aend
170 
171  @dstart
172 
173  Releases the resources associated with an RMvisMap object. This
174  routine is the opposite of rmVismapNew(). The caller should not
175  reference the RMvisMap object after making this call.
176 
177  Returns RM_CHILL upon success, or RM_WHACKED upon failure.
178 
179  @dend
180  * ----------------------------------------------------
181  */
182 RMenum
rmVismapDelete(RMvisMap * toDelete)183 rmVismapDelete (RMvisMap *toDelete)
184 {
185     if (toDelete == NULL)
186     {
187 	rmWarning("rmVismapDelete() warning: the input RMvisMap object is NULL, avoiding NULL pointer free.");
188 	return(RM_WHACKED);
189     }
190     else
191 	free(toDelete);
192     return(RM_CHILL);
193 }
194 
195 
196 /*
197  * ----------------------------------------------------
198  * @Name rmVismapSetColor3D
199  @pstart
200  RMenum rmVismapSetColor3D (RMvisMap *toModify,
201                            int indx,
202 			   const RMcolor3D *newColor)
203  @pend
204 
205  @astart
206  RMvisMap *toModify - input RMvisMap object that will be modified.
207 
208  int index - an integer index of the entry in the RMvisMap that will
209     be modified.
210 
211  const RMcolor3D *newColor - the 4-component color that will be copied
212     into the RMvisMap at location "index".
213 
214  @aend
215 
216  @dstart
217 
218  Use this routine to set the 3-component color of an RMvisMap object.
219  Each entry in the RMvisMap object is a 4-component color (RGBA), and
220  this routine writes over the RGB channels at one such entry at
221  location "index" in the RMvisMap with the caller supplied
222  data. RM_CHILL is returned upon successful modification of the
223  RMvisMap object. RM_WHACKED is returned if "toModify" is NULL, if
224  "indx" is out of range, or if the input RMcolor3D object "newColor"
225  is NULL.
226 
227  @dend
228  * ----------------------------------------------------
229  */
230 RMenum
rmVismapSetColor3D(RMvisMap * toModify,int indx,const RMcolor3D * newColor)231 rmVismapSetColor3D (RMvisMap *toModify,
232 		    int indx,
233 		    const RMcolor3D *newColor)
234 {
235     if ((RM_ASSERT(toModify, "rmVismapSetColor3D() error: the input RMvisMap object is NULL") == RM_WHACKED) ||
236 	(RM_ASSERT(newColor, "rmVismapSetColor3D() error: the input RMcolorD object is NULL") == RM_WHACKED) ||
237 	(private_rmVismapCheckSize((const RMvisMap *)toModify, indx, "rmVismapSetColor3D") == RM_WHACKED))
238 	return(RM_WHACKED);
239 
240     toModify->r[indx] = newColor->r;
241     toModify->g[indx] = newColor->g;
242     toModify->b[indx] = newColor->b;
243 
244     return(RM_CHILL);
245 }
246 
247 
248 /*
249  * ----------------------------------------------------
250  * @Name rmVismapGetColor3D
251  @pstart
252  RMenum rmVismapGetColor3D (const RMvisMap *toQuery,
253 	 	            int indx,
254 		            RMcolor3D *retColor)
255  @pend
256 
257  @astart
258  RMvisMap *toQuery - input RMvisMap object that will be queried.
259 
260  int index - an integer index of the entry in the RMvisMap that will
261     be returned to the caller.
262 
263  RMcolor3D *retColor - a handle to an RMcolor3D object that will be
264     modified to contain the 3-component color at location "indx" from
265     within the RMvisMap "toQuery." 3-component color means the R,G,B
266     channels of the RMvisMap; the alpha channel is ignored.
267  @aend
268 
269  @dstart
270 
271  Copies the 3-component color from the RMvisMap object "toQuery" at
272  location "indx" into the caller supplied object. This routine returns
273  RM_CHILL upon success, or RM_WHACKED if "toQuery" is NULL, if "indx"
274  is out of range, or if the pointer to the caller supplied object is
275  NULL.
276 
277  @dend
278  * ----------------------------------------------------
279  */
280 RMenum
rmVismapGetColor3D(const RMvisMap * toQuery,int indx,RMcolor3D * retColor)281 rmVismapGetColor3D (const RMvisMap *toQuery,
282 		    int indx,
283 		    RMcolor3D *retColor)
284 {
285     if ((RM_ASSERT(toQuery, "rmVismapGetColor3D() error: the input RMvisMap object is NULL") == RM_WHACKED) ||
286 	(RM_ASSERT(retColor, "rmVismapGetColor3D() error: the return RMcolor3D object is NULL") == RM_WHACKED) ||
287 	(private_rmVismapCheckSize(toQuery, indx, "rmVismapGetColor3D") == RM_WHACKED))
288 	return(RM_WHACKED);
289 
290     retColor->r = toQuery->r[indx];
291     retColor->g = toQuery->g[indx];
292     retColor->b = toQuery->b[indx];
293 
294     return(RM_CHILL);
295 }
296 
297 
298 /*
299  * ----------------------------------------------------
300  * @Name rmVismapSetColor4D
301  @pstart
302  RMenum rmVismapSetColor4D (RMvisMap *toModify,
303                             int index,
304 			    const RMcolor4D *newColor)
305  @pend
306 
307  @astart
308  RMvisMap *toModify - input RMvisMap object that will be modified.
309 
310  int index - an integer index of the entry in the RMvisMap that will
311     be modified.
312 
313  const RMcolor4D *newColor - the 4-component color that will be copied
314     into the RMvisMap at location "index"
315  @aend
316 
317  @dstart
318 
319  Use this routine to set the 4-component color of an RMvisMap object.
320  Each entry in the RMvisMap object is a 4-component color, and this
321  routine writes over one such entry at location "index" in the
322  RMvisMap with the caller supplied data. RM_CHILL is returned upon
323  successful modification of the RMvisMap object. RM_WHACKED is
324  returned if "toModify" is NULL, if "indx" is out of range, or if the
325  input RMcolor4D object "newColor" is NULL.
326 
327  @dend
328  * ----------------------------------------------------
329  */
330 RMenum
rmVismapSetColor4D(RMvisMap * toModify,int indx,const RMcolor4D * newColor)331 rmVismapSetColor4D (RMvisMap *toModify,
332 		    int indx,
333 		    const RMcolor4D *newColor)
334 {
335     if ((RM_ASSERT(toModify, "rmVismapSetColor4D() error: the input RMvisMap object is NULL") == RM_WHACKED) ||
336 	(RM_ASSERT(newColor, "rmVismapSetColor4D() error: the input RMcolor4D object is NULL") == RM_WHACKED) ||
337 	(private_rmVismapCheckSize((const RMvisMap *)toModify, indx, "rmVismapSetColor4D") == RM_WHACKED))
338 	return(RM_WHACKED);
339 
340     toModify->r[indx] = newColor->r;
341     toModify->g[indx] = newColor->g;
342     toModify->b[indx] = newColor->b;
343     toModify->a[indx] = newColor->a;
344 
345     return(RM_CHILL);
346 }
347 
348 
349 /*
350  * ----------------------------------------------------
351  * @Name rmVismapGetColor4D
352  @pstart
353  RMenum rmVismapGetColor4D (const RMvisMap *toQuery,
354 	 	            int indx,
355 		            RMcolor4D *retColor)
356  @pend
357 
358  @astart
359  RMvisMap *toQuery - input RMvisMap object that will be queried.
360 
361  int index - an integer index of the entry in the RMvisMap that will
362     be returned to the caller.
363 
364  RMcolor4D *retColor - a handle to an RMcolor4D object that will be
365     modified to contain the 4-component color at location "indx" from
366     within the RMvisMap "toQuery."
367  @aend
368 
369  @dstart
370 
371  Copies the 4-component color from the RMvisMap object "toQuery" at
372  location "indx" into the caller supplied object. This routine returns
373  RM_CHILL upon success, or RM_WHACKED if "toQuery" is NULL, if "indx"
374  is out of range, or if the pointer to the caller supplied object is
375  NULL.
376 
377  @dend
378  * ----------------------------------------------------
379  */
380 RMenum
rmVismapGetColor4D(const RMvisMap * toQuery,int indx,RMcolor4D * retColor)381 rmVismapGetColor4D (const RMvisMap *toQuery,
382 		    int indx,
383 		    RMcolor4D *retColor)
384 {
385     if ((RM_ASSERT(toQuery, "rmVismapGetColor4D() error: the input RMvisMap object is NULL") == RM_WHACKED) ||
386 	(RM_ASSERT(retColor, "rmVismapGetColor4D() error: the return RMcolor4D object is NULL") == RM_WHACKED) ||
387 	(private_rmVismapCheckSize(toQuery, indx, "rmVismapGetColor4D") == RM_WHACKED))
388 	return(RM_WHACKED);
389 
390     retColor->r = toQuery->r[indx];
391     retColor->g = toQuery->g[indx];
392     retColor->b = toQuery->b[indx];
393     retColor->a = toQuery->a[indx];
394 
395     return(RM_CHILL);
396 }
397 
398 
399 /*
400  * ----------------------------------------------------
401  * @Name rmVismapSetTfMin
402  @pstart
403  RMenum rmVismapSetTfMin (RMvisMap *toModify,
404 		          float newTFMin)
405  @pend
406 
407  @astart
408  RMvisMap *toModify - a handle to an RMvisMap object that will be
409     modified by this routine (input).
410 
411  float newTFMin - a floating point value that will be assigned to the
412     RMvisMap object's minimum transfer function attribute.
413  @aend
414 
415  @dstart
416 
417  Use this routine in conjunction with rmVismapSetTfMax to define a
418  linear transfer function for the RMvisMap object. Returns RM_CHILL
419  upon success, or RM_WHACKED if the input RMvisMap object is NULL.
420 
421  @dend
422  * ----------------------------------------------------
423  */
424 RMenum
rmVismapSetTfMin(RMvisMap * toModify,float newTFMin)425 rmVismapSetTfMin (RMvisMap *toModify,
426 		  float newTFMin)
427 {
428     if (RM_ASSERT(toModify, "rmVismapSetTfMin() error: the input RMvisMap is NULL") == RM_WHACKED)
429 	return(RM_WHACKED);
430 
431     toModify->transfer_min = newTFMin;
432     return(RM_CHILL);
433 }
434 
435 
436 /*
437  * ----------------------------------------------------
438  * @Name rmVismapGetTfMin
439  @pstart
440  float rmVismapGetTfMin (const RMvisMap *toQuery)
441  @pend
442 
443  @astart
444  const RMvisMap *toQuery - a handle to an RMvisMap object (input)
445  @aend
446 
447  @dstart
448 
449  Returns to the caller a floating point value that is the RMvisMap
450  object's transfer function lower bound.
451 
452  @dend
453  * ----------------------------------------------------
454  */
455 float
rmVismapGetTfMin(const RMvisMap * toQuery)456 rmVismapGetTfMin (const RMvisMap *toQuery)
457 {
458     if (RM_ASSERT(toQuery, "rmVismapGetTfMin error() the input RMvisMap object is NULL") == RM_WHACKED)
459 	return(0.0F);
460 
461     return(toQuery->transfer_min);
462 }
463 
464 
465 /*
466  * ----------------------------------------------------
467  * @Name rmVismapSetTfMax
468  @pstart
469  RMenum rmVismapSetTfMax (RMvisMap *toModify,
470 		          float newTFMax)
471  @pend
472 
473  @astart
474 
475  RMvisMap *toModify - a handle to an RMvisMap object that will be
476     modified by this routine (input).
477 
478  float newTFMax - a floating point value that will be assigned to the
479     RMvisMap object's maximum transfer function attribute (input).
480  @aend
481 
482  @dstart
483 
484  Use this routine in conjunction with rmVismapSetTfMin to define a
485  linear transfer function for the RMvisMap object. Returns RM_CHILL
486  upon success, or RM_WHACKED if the input RMvisMap object is NULL.
487 
488  @dend
489  * ----------------------------------------------------
490  */
491 RMenum
rmVismapSetTfMax(RMvisMap * toModify,float newTFMax)492 rmVismapSetTfMax (RMvisMap *toModify,
493 		  float newTFMax)
494 {
495     if (RM_ASSERT(toModify, "rmVismapSetTfMax() error: the input RMvisMap is NULL") == RM_WHACKED)
496 	return(RM_WHACKED);
497 
498     toModify->transfer_max = newTFMax;
499     return(RM_CHILL);
500 }
501 
502 
503 /*
504  * ----------------------------------------------------
505  * @Name rmVismapGetTfMax
506  @pstart
507  float rmVismapGetTfMax (const RMvisMap *toQuery)
508  @pend
509 
510  @astart
511  const RMvisMap *toQuery - a handle to an RMvisMap object (input)
512  @aend
513 
514  @dstart
515 
516  Returns to the caller a floating point value that is the RMvisMap
517  object's transfer function upper bound.
518 
519  @dend
520  * ----------------------------------------------------
521  */
522 float
rmVismapGetTfMax(const RMvisMap * toQuery)523 rmVismapGetTfMax (const RMvisMap *toQuery)
524 {
525     if (RM_ASSERT(toQuery,"rmVismapGetTfMax() error: the input RMvisMap object is NULL") == RM_WHACKED)
526 	return(0.0F);
527 
528     return(toQuery->transfer_max);
529 }
530 
531 
532 /*
533  * ----------------------------------------------------
534  * @Name rmVismapIndexFromData
535  @pstart
536  int rmVismapIndexFromData (const RMvisMap *map,
537                             float val)
538  @pend
539 
540  @astart
541  const RMvisMap *map - a handle to an RMvisMap object (input).
542 
543  float val - a floating point value (input).
544  @aend
545 
546  @dstart
547 
548  Use this routine to compute an index from a raw data value. RMvisMap
549  objects contain internal parameters to define a transfer function
550  (see rmVismapSetTfMin() and rmVismapSetTfMax() ). This routine
551  computes an integer index thus: ((val-min)/(max-min))*(size-1). The
552  return value is clamped to be in the range 0..size-1, where "size" is
553  the number of entries in the RMvisMap object.
554 
555  @dend
556  * ----------------------------------------------------
557  */
558 int
rmVismapIndexFromData(const RMvisMap * map,float val)559 rmVismapIndexFromData (const RMvisMap *map,
560 		       float val)
561 {
562     /* look through the bracket values in the map, return the index into the map */
563     int   index;
564     float fval;
565 
566     if (RM_ASSERT(map, "rmVismapIndexFromData() error: the input RMvisMap object is NULL") == RM_WHACKED)
567 	return(0);
568 
569     fval = ((val-map->transfer_min) / (map->transfer_max-map->transfer_min));
570 
571     if (fval < 0.0)
572         fval = 0.0;
573     else
574        if (fval > 1.0)
575 	  fval = 1.0;
576 
577     index = (float)(map->nentries - 1) * fval;
578     return(index);
579 }
580 
581 
582 /*
583  * ----------------------------------------------------
584  * @Name rmVismapSetSize
585  @pstart
586  RMenum rmVismapSetSize (RMvisMap *toModify,
587 		         int newSize)
588  @pend
589 
590  @astart
591  RMvisMap *toModify - a handle to an RMvisMap object.
592 
593  int newSize - an integer value defining the new number of entries in
594     the RMvisMap object "toModify."
595  @aend
596 
597  @dstart
598 
599  This routine is used to modify the number of entries in the RMvisMap
600  object. The new requested size must be greater than 0 and less than
601  256. As of 1/15/2000, 256 is the current maximum and default size of
602  the RMvisMap object. This routine does not cause any internal tables
603  to be realloced, it just changes the size attribute of the table. The
604  size attribute is checked by routines that set/get RMvisMap entries
605  in validity checking input.
606 
607  This routine will return RM_CHILL to the caller upon success, or
608  RM_WHACKED if the input RMvisMap object is NULL or if the "newSize"
609  parameter is out of range.
610 
611  @dend
612  * ----------------------------------------------------
613  */
614 RMenum
rmVismapSetSize(RMvisMap * toModify,int newSize)615 rmVismapSetSize (RMvisMap *toModify,
616 		 int newSize)
617 {
618     if (RM_ASSERT(toModify, "rmVismapSetSize() error: the input RMvisMap object is NULL") == RM_WHACKED)
619 	return(RM_WHACKED);
620     if ((newSize <= 0) || (newSize > RMV_DEFAULT_MAP_SIZE ))
621     {
622 	rmError(" rmVismapSetSize() the requested newSize is either too large or too small.");
623 	return(RM_WHACKED);
624     }
625 
626     /*
627      * TODO:
628      *
629      * at this time (1/15/2000) the size of the R,G,B,A tables in the
630      * RMvisMap object is fixed, defined by the constant RMV_DEFAULT_MAP_SIZE.
631      * at some point in the future, we will want to dynamically allocate
632      * those tables. when we do that, we'll need to change this set size
633      * routine to realloc the tables to the new requested size.
634      */
635     toModify->nentries = newSize;
636     return(RM_CHILL);
637 }
638 
639 
640 /*
641  * ----------------------------------------------------
642  * @Name rmVismapGetSize
643  @pstart
644  int rmVismapGetSize (const RMvisMap *toQuery)
645  @pend
646 
647  @astart
648 
649  const RMvisMap *toQuery - a handle to the RMvisMap object to be
650     queried.
651  @aend
652 
653  @dstart
654 
655  Returns to the caller the number of entries in the visualization colormap
656  of the of the RMvisMap object. A non-negative integer is returned upon
657  success, or -1 is returned if the input RMvisMap object is NULL.
658 
659  @dend
660  * ----------------------------------------------------
661  */
662 int
rmVismapGetSize(const RMvisMap * toQuery)663 rmVismapGetSize (const RMvisMap *toQuery)
664 {
665     if (RM_ASSERT(toQuery, "rmVismapGetSize() error: input RMvisMap pointer is NULL.") == RM_WHACKED)
666 	return(-1);
667     return(toQuery->nentries);
668 }
669 
670 
671 /*
672  * ----------------------------------------------------
673  * @Name rmVismapSetAlpha
674  @pstart
675  RMenum rmVismapSetAlpha (RMvisMap *toModify,
676 		          int indx,
677 			  float newAlpha)
678  @pend
679 
680  @astart
681  RMvisMap *toModify - a handle to an RMvisMap object (input).
682 
683  int indx - an integer value specifying which entry of the RMvisMap
684     object will be modified by this routine (input).
685 
686  float newAlpha - a floating point value that will be copied into the
687     RMvisMap object "toModify" at location "indx". Alpha values
688     usually range between 0.0 and 1.0.
689  @aend
690 
691  @dstart
692 
693  Sets that alpha component of the 4-component color in the RMvisMap
694  object "toModify" at entry "indx." Returns RM_CHILL to the caller if
695  successful.  RM_WHACKED is returned if "toModify" is NULL, or if
696  "indx" is out of range.
697 
698  @dend
699  * ----------------------------------------------------
700  */
701 RMenum
rmVismapSetAlpha(RMvisMap * toModify,int indx,float value)702 rmVismapSetAlpha (RMvisMap *toModify,
703 		  int indx,
704 		  float value)
705 {
706     if ((RM_ASSERT(toModify, "rmVismapSetAlpha() error: the input RMvisMap object is NULL") == RM_WHACKED) ||
707 	(private_rmVismapCheckSize(toModify, indx, "rmVismapSetAlpha") == RM_WHACKED))
708 	return(RM_WHACKED);
709 
710     toModify->a[indx] = value;
711     return(RM_CHILL);
712 }
713 
714 
715 /*
716  * ----------------------------------------------------
717  * @Name rmVismapGetAlpha
718  @pstart
719  float rmVismapGetAlpha (const RMvisMap *toQuery,
720 	 	         int indx)
721  @pend
722 
723  @astart
724  const RMvisMap *toQuery - a handle to an RMvisMap object to be
725     queried (input).
726 
727  int indx - the index of the entry in the RMvisMap object to query
728     (input).
729  @aend
730 
731  @dstart
732 
733  Returns to the caller the alpha component of the RMvisMap object at
734  entry "indx." If "indx" is out of range, rmWarning() is called
735  issuing an error message, and -1.0 is returned to the caller. Alpha
736  values usually range between 0.0 and 1.0.
737 
738  @dend
739  * ----------------------------------------------------
740  */
741 float
rmVismapGetAlpha(const RMvisMap * toQuery,int indx)742 rmVismapGetAlpha (const RMvisMap *toQuery,
743 		  int indx)
744 {
745     if ((RM_ASSERT(toQuery, "rmVismapGetAlpha() error: the input RMvisMap object is NULL") == RM_WHACKED) ||
746 	(private_rmVismapCheckSize(toQuery, indx, "rmVismapGetAlpha") == RM_WHACKED))
747 	return(0.0F);
748     else
749 	return(toQuery->a[indx]);
750 }
751 
752 
753 /*
754  * ----------------------------------------------------
755  * @Name rmDefaultVismap
756  @pstart
757  RMvisMap *rmDefaultVismap (void)
758  @pend
759 
760  @astart
761  No arguments.
762  @aend
763 
764  @dstart
765 
766  This routine performs a two-fold function. First, it creates a new
767  RMvisMap object containing 256 entries. Second, it assigns default
768  values to the RGBA channels of the new colormap. A handle to the new
769  RMvisMap object is returned to the caller. When caller no longer
770  needs the RMvisMap object, use "rmVismapDelete()" to free the object.
771  The default colormap will be set to:
772 
773  1. A hue ramp from .66 to 0.0 (blue-cyan-green-yellow-orange-red)
774  2. Constant saturation & brightness of 1.0
775  3. Alpha ramp from 0..1 (low to high)
776  4. transfer function min/max of 0..1
777 
778  @dend
779  * ----------------------------------------------------
780  */
781 RMvisMap *
rmDefaultVismap(void)782 rmDefaultVismap (void)
783 {
784     int       i, n;
785     float     h, dh, s, v, a, da;
786     RMvisMap *t;
787     RMcolor3D rgb;
788 
789     n = RMV_DEFAULT_MAP_SIZE;
790 
791     t = rmVismapNew(n);
792     if (t == NULL)
793     {
794 	rmError(" rmDefaultVismap() error: unable to allocate a new RMvisMap object.");
795 	return(NULL);
796     }
797 
798     h = 0.66F;
799     dh = -0.66 / (float)(n - 1);
800     s = 1.0;
801     v = 1.0;
802     a = 0.0;
803     da = 1.0 / (float)(n - 1);
804 
805     for (i = 0; i < n; i++)
806     {
807         rmHSVtoRGB(h, s, v, &(rgb.r), &(rgb.g), &(rgb.b));
808         rmVismapSetColor3D(t, i, &rgb);
809 	rmVismapSetAlpha(t, i, a);
810 
811 	h += dh;
812 	a += da;
813     }
814 
815     rmVismapSetTfMin(t, 0.0F);
816     rmVismapSetTfMax(t, 1.0F);
817 
818     return(t);
819 }
820 
821 
822 /* PRIVATE
823  *
824  * private_rmVismapCheckSize performs a validity/range check operation. The
825  * input parameter "indx" is compared to the RMvisMap object's size attribute.
826  * If "indx" is greater than or equal to zero, but less than the RMvisMap
827  * object's size attribute, this routine returns RM_CHILL. Otherwise,
828  * rmWarning is called with a descriptive error message, and RM_WHACKED
829  * is returned to the caller.
830  */
831 RMenum
private_rmVismapCheckSize(const RMvisMap * v,int indx,char * funcName)832 private_rmVismapCheckSize (const RMvisMap *v,
833 			   int indx,
834 			   char *funcName)
835 {
836     if ((indx < 0) || (indx >= rmVismapGetSize(v)))
837     {
838 	char buf[1024];
839 
840 	if (strlen(funcName) > 900)
841 	{
842 	    rmWarning("private_rmVismapCheckSize() warning: the index into the RMvisMap object is out of range, and the string length of the function name is unreasonable.");
843 	    return(RM_WHACKED);
844 	}
845 
846 	sprintf(buf, "in function %s the index (value = %d) is out of range (<= 0 or >= %d) \n", funcName, indx, rmVismapGetSize(v));
847 	rmWarning(buf);
848 	return(RM_WHACKED);
849     }
850     else
851 	return(RM_CHILL);
852 
853 }
854 /* EOF */
855