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