GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
Loading...
Searching...
No Matches
gvl.c
Go to the documentation of this file.
1/*!
2 \file lib/ogsf/gvl.c
3
4 \brief OGSF library - loading and manipulating volumes (lower level
5 functions)
6
7 GRASS OpenGL gsurf OGSF Library
8
9 (C) 1999-2008 by the GRASS Development Team
10
11 This program is free software under the
12 GNU General Public License (>=v2).
13 Read the file COPYING that comes with GRASS
14 for details.
15
16 \author Bill Brown, UI-GMSL (May 1997)
17 \author Tomas Paudits (February 2004)
18 \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
19 */
20
21#include <stdlib.h>
22
23#include <grass/gis.h>
24#include <grass/ogsf.h>
25
26#include "gsget.h"
27
28#define FIRST_VOL_ID 81721
29
30static geovol *Vol_top = NULL;
31
32/*!
33 \brief Get volume set structure
34
35 \param id volume set id
36
37 \return pointer to geovol struct
38 \return NULL on failure
39 */
40geovol *gvl_get_vol(int id)
41{
42 geovol *gvl;
43
44 G_debug(5, "gvl_get_vol():");
45
46 for (gvl = Vol_top; gvl; gvl = gvl->next) {
47 if (gvl->gvol_id == id) {
48 G_debug(5, " id=%d", id);
49 return (gvl);
50 }
51 }
52
53 return (NULL);
54}
55
56/*!
57 \brief Get previous volume
58
59 \param id current volume set id
60
61 \return pointer to geovol struct
62 \return NULL on failure
63 */
64geovol *gvl_get_prev_vol(int id)
65{
66 geovol *pv;
67
68 G_debug(5, "gvl_get_prev_vol");
69
70 for (pv = Vol_top; pv; pv = pv->next) {
71 if (pv->gvol_id == id - 1) {
72 return (pv);
73 }
74 }
75
76 return (NULL);
77}
78
79/*!
80 \brief Get all volumes
81
82 \param[out] list of geovol structs
83
84 \return number of available volume sets
85 */
86int gvl_getall_vols(geovol **gvols)
87{
88 geovol *gvl;
89 int i;
90
91 G_debug(5, "gvl_getall_vols");
92
93 for (i = 0, gvl = Vol_top; gvl; gvl = gvl->next, i++) {
94 gvols[i] = gvl;
95 }
96
97 return (i);
98}
99
100/*!
101 \brief Get number of loaded volume sets
102
103 \return number of volumes
104 */
106{
107 geovol *gvl;
108 int i;
109
110 for (i = 0, gvl = Vol_top; gvl; gvl = gvl->next, i++)
111 ;
112
113 G_debug(5, "gvl_num_vols(): num=%d", i);
114
115 return (i);
116}
117
118/*!
119 \brief Get last volume set from the list
120
121 \return pointer to geovol struct
122 \return NULL on failure
123 */
124geovol *gvl_get_last_vol(void)
125{
126 geovol *lvl;
127
128 G_debug(5, "gvl_get_last_vol");
129
130 if (!Vol_top) {
131 return (NULL);
132 }
133
134 for (lvl = Vol_top; lvl->next; lvl = lvl->next)
135 ;
136
137 G_debug(5, " last vol id: %d", lvl->gvol_id);
138
139 return (lvl);
140}
141
142/*!
143 \brief Allocate new volume set and add it to the list
144
145 \return pointer to geovol struct
146 \return NULL on failure
147 */
148geovol *gvl_get_new_vol(void)
149{
150 geovol *nvl, *lvl;
151
152 G_debug(5, "gvl_get_new_vol()");
153
154 nvl = (geovol *)G_malloc(sizeof(geovol)); /* G_fatal_error */
155 if (!nvl) {
156 return (NULL);
157 }
158
159 if ((lvl = gvl_get_last_vol())) {
160 lvl->next = nvl;
161 nvl->gvol_id = lvl->gvol_id + 1;
162 }
163 else {
164 Vol_top = nvl;
165 nvl->gvol_id = FIRST_VOL_ID;
166 }
167
168 nvl->next = NULL;
169
170 G_debug(5, " id=%d", nvl->gvol_id);
171
172 return (nvl);
173}
174
175/*!
176 \brief Initialize geovol structure
177
178 \param gvl pointer to geovol struct
179 \param ox,oy,oz
180 \param rows number of rows
181 \param cols number of cols
182 \param xres,yres,zres x/y/z resolution value
183
184 \return -1 on failure
185 \return 1 on success
186 */
187int gvl_init_vol(geovol *gvl, double ox, double oy, double oz, int rows,
188 int cols, int depths, double xres, double yres, double zres)
189{
190 G_debug(5, "gvl_init_vol() id=%d", gvl->gvol_id);
191
192 if (!gvl) {
193 return (-1);
194 }
195
196 gvl->ox = ox;
197 gvl->oy = oy;
198 gvl->oz = oz;
199 gvl->rows = rows;
200 gvl->cols = cols;
201 gvl->depths = depths;
202 gvl->xres = xres;
203 gvl->yres = yres;
204 gvl->zres = zres;
205
206 gvl->xmin = ox;
207 gvl->xmax = ox + (cols - 1) * xres;
208 gvl->xrange = gvl->xmax - gvl->xmin;
209 gvl->ymin = oy;
210 gvl->ymax = oy + (rows - 1) * yres;
211 gvl->yrange = gvl->ymax - gvl->ymin;
212 gvl->zmin = oz;
213 gvl->zmax = oz + (depths - 1) * zres;
214 gvl->zrange = gvl->zmax - gvl->zmin;
215
216 gvl->x_trans = gvl->y_trans = gvl->z_trans = 0.0;
217 gvl->draw_wire = 0;
218
219 gvl->n_isosurfs = 0;
220 G_zero(gvl->isosurf, sizeof(geovol_isosurf *) * MAX_ISOSURFS);
221 gvl->isosurf_x_mod = 1;
222 gvl->isosurf_y_mod = 1;
223 gvl->isosurf_z_mod = 1;
224 gvl->isosurf_draw_mode = DM_GOURAUD;
225
226 gvl->n_slices = 0;
227 G_zero(gvl->slice, sizeof(geovol_slice *) * MAX_SLICES);
228 gvl->slice_x_mod = 1;
229 gvl->slice_y_mod = 1;
230 gvl->slice_z_mod = 1;
231 gvl->slice_draw_mode = DM_GOURAUD;
232
233 gvl->hfile = -1;
234 gvl->clientdata = NULL;
235
236 return (1);
237}
238
239/*!
240 \brief Remove volume set from list
241
242 \param id volume set id
243 */
244void gvl_delete_vol(int id)
245{
246 geovol *fvl;
247
248 G_debug(5, "gvl_delete_vol");
249
250 fvl = gvl_get_vol(id);
251
252 if (fvl) {
253 gvl_free_vol(fvl);
254 }
255
256 return;
257}
258
259/*!
260 \brief Free geovol struct
261
262 \param fvl pointer to geovol struct
263
264 \return -1 on failure
265 \return 1 on success
266 */
267int gvl_free_vol(geovol *fvl)
268{
269 geovol *gvl;
270 int found = 0;
271
272 G_debug(5, "gvl_free_vol");
273
274 if (Vol_top) {
275 if (fvl == Vol_top) {
276 if (Vol_top->next) {
277 /* can't free top if last */
278 found = 1;
279 Vol_top = fvl->next;
280 }
281 else {
282 gvl_free_volmem(fvl);
283 G_free(fvl);
284 Vol_top = NULL;
285 }
286 }
287 else {
288 for (gvl = Vol_top; gvl && !found; gvl = gvl->next) {
289 /* can't free top */
290 if (gvl->next) {
291 if (gvl->next == fvl) {
292 found = 1;
293 gvl->next = fvl->next;
294 }
295 }
296 }
297 }
298
299 if (found) {
300 gvl_free_volmem(fvl);
301 G_free(fvl);
302 fvl = NULL;
303 }
304
305 return (1);
306 }
307
308 return (-1);
309}
310
311/*!
312 \brief Free geovol struct memory
313
314 \param fvl pointer to geovol struct
315 */
316void gvl_free_volmem(geovol *fvl)
317{
318 if (0 < fvl->hfile)
319 gvl_file_free_datah(fvl->hfile);
320
321 return;
322}
323
324/*!
325 \brief Debug volume fields
326
327 \param gvl pointer to geovol struct
328 */
329void print_vol_fields(geovol *gvl)
330{
331 G_debug(5, "ID: %d", gvl->gvol_id);
332 G_debug(5, "cols: %d rows: %d depths: %d", gvl->cols, gvl->rows,
333 gvl->depths);
334 G_debug(5, "ox: %lf oy: %lf oz: %lf", gvl->ox, gvl->oy, gvl->oz);
335 G_debug(5, "xres: %lf yres: %lf zres: %lf", gvl->xres, gvl->yres,
336 gvl->zres);
337 G_debug(5, "xmin: %f ymin: %f zmin: %f", gvl->xmin, gvl->ymin, gvl->zmin);
338 G_debug(5, "xmax: %f ymax: %f zmax: %f", gvl->xmax, gvl->ymax, gvl->zmax);
339 G_debug(5, "x_trans: %f y_trans: %f z_trans: %f", gvl->x_trans,
340 gvl->y_trans, gvl->z_trans);
341
342 return;
343}
344
345/*!
346 \brief Get volume x-extent value
347
348 \param gvl pointer to geovol struct
349 \param[out] min x-min value
350 \param[out] max y-max value
351
352 \return 1
353 */
354int gvl_get_xextents(geovol *gvl, float *min, float *max)
355{
356 *min = gvl->xmin + gvl->x_trans;
357 *max = gvl->xmax + gvl->x_trans;
358
359 return (1);
360}
361
362/*!
363 \brief Get volume y-extent value
364
365 \param gvl pointer to geovol struct
366 \param[out] min y-min value
367 \param[out] max y-max value
368
369 \return 1
370 */
371int gvl_get_yextents(geovol *gvl, float *min, float *max)
372{
373 *min = gvl->ymin + gvl->y_trans;
374 *max = gvl->ymax + gvl->y_trans;
375
376 return (1);
377}
378
379/*!
380 \brief Get volume z-extent value
381
382 \param gvl pointer to geovol struct
383 \param[out] min z-min value
384 \param[out] max z-max value
385
386 \return 1
387 */
388int gvl_get_zextents(geovol *gvl, float *min, float *max)
389{
390 *min = gvl->zmin + gvl->z_trans;
391 *max = gvl->zmax + gvl->z_trans;
392
393 return (1);
394}
395
396/*!
397 \brief Get volume x-range value
398
399 \param[out] min x-min value
400 \param[out] max x-max value
401
402 \return 1
403 */
404int gvl_get_xrange(float *min, float *max)
405{
406 geovol *gvl;
407 float tmin, tmax;
408
409 if (Vol_top) {
410 gvl_get_xextents(Vol_top, &tmin, &tmax);
411 *min = tmin;
412 *max = tmax;
413 }
414 else {
415 return (-1);
416 }
417
418 for (gvl = Vol_top->next; gvl; gvl = gvl->next) {
419 gvl_get_xextents(gvl, &tmin, &tmax);
420
421 if (tmin < *min) {
422 *min = tmin;
423 }
424
425 if (tmax > *max) {
426 *max = tmax;
427 }
428 }
429
430 return (1);
431}
432
433/*!
434 \brief Get volume y-range value
435
436 \param[out] min y-min value
437 \param[out] max y-max value
438
439 \return 1
440 */
441int gvl_get_yrange(float *min, float *max)
442{
443 geovol *gvl;
444 float tmin, tmax;
445
446 if (Vol_top) {
447 gvl_get_yextents(Vol_top, &tmin, &tmax);
448 *min = tmin;
449 *max = tmax;
450 }
451 else {
452 return (-1);
453 }
454
455 for (gvl = Vol_top->next; gvl; gvl = gvl->next) {
456 gvl_get_yextents(gvl, &tmin, &tmax);
457
458 if (tmin < *min) {
459 *min = tmin;
460 }
461
462 if (tmax > *max) {
463 *max = tmax;
464 }
465 }
466
467 return (1);
468}
469
470/*!
471 \brief Get volume z-range value
472
473 \param[out] min z-min value
474 \param[out] max z-max value
475
476 \return 1
477 */
478int gvl_get_zrange(float *min, float *max)
479{
480 geovol *gvl;
481 float tmin, tmax;
482
483 if (Vol_top) {
484 gvl_get_zextents(Vol_top, &tmin, &tmax);
485 *min = tmin;
486 *max = tmax;
487 }
488 else {
489 return (-1);
490 }
491
492 for (gvl = Vol_top->next; gvl; gvl = gvl->next) {
493 gvl_get_zextents(gvl, &tmin, &tmax);
494
495 if (tmin < *min) {
496 *min = tmin;
497 }
498
499 if (tmax > *max) {
500 *max = tmax;
501 }
502 }
503
504 return (1);
505}
506
507/************************************************************************/
508/* ISOSURFACES */
509
510/************************************************************************/
511
512/*!
513 \brief Initialize geovol_isosurf struct
514
515 \param isosurf pointer to geovol_isosurf struct
516
517 \return -1 on failure
518 \return 1 on success
519 */
520int gvl_isosurf_init(geovol_isosurf *isosurf)
521{
522 int i;
523
524 G_debug(5, "gvl_isosurf_init");
525
526 if (!isosurf)
527 return (-1);
528
529 for (i = 0; i < MAX_ATTS; i++) {
530 isosurf->att[i].att_src = NOTSET_ATT;
531 isosurf->att[i].constant = 0.;
532 isosurf->att[i].hfile = -1;
533 isosurf->att[i].user_func = NULL;
534 isosurf->att[i].att_data = NULL;
535 isosurf->att[i].changed = 0;
536 }
537
538 isosurf->data = NULL;
539 isosurf->data_desc = 0;
540 isosurf->inout_mode = 0;
541
542 return (1);
543}
544
545/*!
546 \brief Free geovol_isosurf struct
547
548 \param isosurf pointer to geovol_isosurf struct
549
550 \return -1 on failure
551 \return 1 on success
552 */
553int gvl_isosurf_freemem(geovol_isosurf *isosurf)
554{
555 int i;
556
557 G_debug(5, "gvl_isosurf_freemem");
558
559 if (!isosurf)
560 return (-1);
561
562 for (i = 0; i < MAX_ATTS; i++) {
563 gvl_isosurf_set_att_src(isosurf, i, NOTSET_ATT);
564 }
565
566 G_free(isosurf->data);
567
568 return (1);
569}
570
571/*!
572 \brief Get isosurface of given volume set
573
574 \param id volume set id
575 \param isosurf_id isosurface id (0 - MAX_ISOSURFS)
576
577 \return pointer to geovol_isosurf struct
578 \return NULL on failure
579 */
580geovol_isosurf *gvl_isosurf_get_isosurf(int id, int isosurf_id)
581{
582 geovol *gvl;
583
584 G_debug(5, "gvl_isosurf_get_isosurf(): id=%d isosurf=%d", id, isosurf_id);
585
586 gvl = gvl_get_vol(id);
587
588 if (gvl) {
589 if ((isosurf_id < 0) || (isosurf_id > (gvl->n_isosurfs - 1)))
590 return (NULL);
591
592 return gvl->isosurf[isosurf_id];
593 }
594
595 return (NULL);
596}
597
598/*!
599 \brief Get attribute source
600
601 \param isosurf pointer to geovol_isosurf struct
602 \param desc attribute id
603
604 \return -1 on failure
605 \return attribute value
606 */
607int gvl_isosurf_get_att_src(geovol_isosurf *isosurf, int desc)
608{
609 G_debug(5, "isosurf_get_att_src");
610
611 if (!LEGAL_ATT(desc)) {
612 return (-1);
613 }
614
615 if (isosurf) {
616 return (isosurf->att[desc].att_src);
617 }
618
619 return (-1);
620}
621
622/*!
623 \brief Set attribute source
624
625 \param isosurf pointer to geovol_isosurf struct
626 \param desc attribute id
627 \param src attribute value
628
629 \return -1 on failure
630 \return 1 on success
631 */
632int gvl_isosurf_set_att_src(geovol_isosurf *isosurf, int desc, int src)
633{
634 G_debug(5, "gvl_isosurf_set_att_src");
635
636 /* check if old source was MAP_ATT, deattach volfile */
637 if (MAP_ATT == gvl_isosurf_get_att_src(isosurf, desc)) {
638 gvl_file_free_datah(isosurf->att[desc].hfile);
639
640 if (desc == ATT_COLOR) {
641 Gvl_unload_colors_data(isosurf->att[desc].att_data);
642 }
643 }
644
645 if (isosurf && LEGAL_SRC(src)) {
646 isosurf->att[desc].att_src = src;
647 gvl_isosurf_set_att_changed(isosurf, desc);
648
649 return (1);
650 }
651
652 return (-1);
653}
654
655/*!
656 \brief Set isosurface attribute constant
657
658 \param isosurf pointer to geovol_isosurf struct
659 \param desc attribute descriptor
660 \param constant attribute value
661
662 \return -1 on failure
663 \return 1 on success
664 */
665int gvl_isosurf_set_att_const(geovol_isosurf *isosurf, int desc, float constant)
666{
667 G_debug(5, "gvl_isosurf_set_att_const(): att=%d, const=%f", desc, constant);
668
669 if (isosurf) {
670 isosurf->att[desc].constant = constant;
671
672 gvl_isosurf_set_att_src(isosurf, desc, CONST_ATT);
673
674 return (1);
675 }
676
677 return (-1);
678}
679
680/*!
681 \brief Set attribute map
682
683 \param isosurf pointer to geovol_isosurf struct
684 \param desc attribute id
685 \param filename filename
686
687 \return -1 on failure
688 \return 1 on success
689 */
690int gvl_isosurf_set_att_map(geovol_isosurf *isosurf, int desc,
691 const char *filename)
692{
693 int hfile;
694
695 G_debug(5, "gvl_isosurf_set_att_map(): att=%d map=%s", desc, filename);
696
697 if (isosurf) {
698 if (0 > (hfile = gvl_file_newh(filename, VOL_FTYPE_RASTER3D)))
699 return (-1);
700
701 gvl_isosurf_set_att_src(isosurf, desc, MAP_ATT);
702
703 isosurf->att[desc].hfile = hfile;
704
705 if (ATT_COLOR == desc) {
706 Gvl_load_colors_data(&(isosurf->att[desc].att_data), filename);
707 }
708 return (1);
709 }
710
711 return (-1);
712}
713
714/*!
715 \brief Set attribute changed
716
717 \param isosurf pointer to geovol_isosurf struct
718 \param desc attribute id
719
720 \return -1 on failure
721 \return 1 on success
722 */
723int gvl_isosurf_set_att_changed(geovol_isosurf *isosurf, int desc)
724{
725 int i;
726
727 G_debug(5, "gvl_isosurf_set_att_changed");
728
729 if (isosurf && LEGAL_ATT(desc)) {
730 isosurf->att[desc].changed = 1;
731
732 if ((desc == ATT_TOPO) || (desc == ATT_MASK)) {
733 for (i = 1; i < MAX_ATTS; i++)
734 isosurf->att[i].changed = 1;
735 }
736
737 return (1);
738 }
739
740 return (-1);
741}
742
743/************************************************************************/
744/* SLICES */
745
746/************************************************************************/
747
748/*!
749 \brief Initialize geovol_slice struct
750
751 \param slice pointer to geovol_slice struct
752
753 \return -1 on failure
754 \return 1 on success
755 */
756int gvl_slice_init(geovol_slice *slice)
757{
758 G_debug(5, "gvl_slice_init");
759
760 if (!slice)
761 return (-1);
762
763 slice->data = NULL;
764 slice->changed = 0;
765 slice->mode = 1;
766 slice->transp = 0;
767
768 slice->z1 = 0;
769 slice->z2 = 99;
770
771 return (1);
772}
773
774/*!
775 \brief Free geovol_slice struct
776
777 \param slice pointer to geovol_slice struct
778
779 \return -1 on failure
780 \return 1 on success
781 */
782int gvl_slice_freemem(geovol_slice *slice)
783{
784 G_debug(5, "gvl_slice_freemem");
785
786 if (!slice)
787 return (-1);
788
789 G_free(slice->data);
790
791 return (1);
792}
793
794/*!
795 \brief Get geovol_slice struct
796
797 \param id volume set id
798 \param slice_id slice id
799
800 \return pointer to geovol_slice struct
801 \return NULL on failure
802 */
803geovol_slice *gvl_slice_get_slice(int id, int slice_id)
804{
805 geovol *gvl;
806
807 gvl = gvl_get_vol(id);
808
809 if (gvl) {
810 if ((slice_id < 0) || (slice_id > (gvl->n_slices - 1)))
811 return (NULL);
812
813 return gvl->slice[slice_id];
814 }
815
816 return (NULL);
817}
void G_free(void *buf)
Free allocated memory.
Definition alloc.c:150
#define NULL
Definition ccmath.h:32
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition debug.c:66
int Gvl_unload_colors_data(void *color_data)
Unload color table.
Definition gvl3.c:65
int Gvl_load_colors_data(void **color_data, const char *name)
Load color table.
Definition gvl3.c:34
void gvl_free_volmem(geovol *fvl)
Free geovol struct memory.
Definition gvl.c:316
geovol * gvl_get_new_vol(void)
Allocate new volume set and add it to the list.
Definition gvl.c:148
int gvl_get_yrange(float *min, float *max)
Get volume y-range value.
Definition gvl.c:441
int gvl_get_xextents(geovol *gvl, float *min, float *max)
Get volume x-extent value.
Definition gvl.c:354
int gvl_isosurf_init(geovol_isosurf *isosurf)
Initialize geovol_isosurf struct.
Definition gvl.c:520
int gvl_init_vol(geovol *gvl, double ox, double oy, double oz, int rows, int cols, int depths, double xres, double yres, double zres)
Initialize geovol structure.
Definition gvl.c:187
geovol * gvl_get_prev_vol(int id)
Get previous volume.
Definition gvl.c:64
int gvl_getall_vols(geovol **gvols)
Get all volumes.
Definition gvl.c:86
void print_vol_fields(geovol *gvl)
Debug volume fields.
Definition gvl.c:329
int gvl_isosurf_set_att_map(geovol_isosurf *isosurf, int desc, const char *filename)
Set attribute map.
Definition gvl.c:690
int gvl_slice_freemem(geovol_slice *slice)
Free geovol_slice struct.
Definition gvl.c:782
geovol * gvl_get_vol(int id)
Get volume set structure.
Definition gvl.c:40
int gvl_isosurf_get_att_src(geovol_isosurf *isosurf, int desc)
Get attribute source.
Definition gvl.c:607
int gvl_isosurf_freemem(geovol_isosurf *isosurf)
Free geovol_isosurf struct.
Definition gvl.c:553
geovol_slice * gvl_slice_get_slice(int id, int slice_id)
Get geovol_slice struct.
Definition gvl.c:803
geovol_isosurf * gvl_isosurf_get_isosurf(int id, int isosurf_id)
Get isosurface of given volume set.
Definition gvl.c:580
int gvl_get_zrange(float *min, float *max)
Get volume z-range value.
Definition gvl.c:478
int gvl_isosurf_set_att_src(geovol_isosurf *isosurf, int desc, int src)
Set attribute source.
Definition gvl.c:632
#define FIRST_VOL_ID
Definition gvl.c:28
int gvl_get_xrange(float *min, float *max)
Get volume x-range value.
Definition gvl.c:404
int gvl_isosurf_set_att_changed(geovol_isosurf *isosurf, int desc)
Set attribute changed.
Definition gvl.c:723
int gvl_get_zextents(geovol *gvl, float *min, float *max)
Get volume z-extent value.
Definition gvl.c:388
int gvl_isosurf_set_att_const(geovol_isosurf *isosurf, int desc, float constant)
Set isosurface attribute constant.
Definition gvl.c:665
geovol * gvl_get_last_vol(void)
Get last volume set from the list.
Definition gvl.c:124
int gvl_get_yextents(geovol *gvl, float *min, float *max)
Get volume y-extent value.
Definition gvl.c:371
int gvl_slice_init(geovol_slice *slice)
Initialize geovol_slice struct.
Definition gvl.c:756
void gvl_delete_vol(int id)
Remove volume set from list.
Definition gvl.c:244
int gvl_num_vols(void)
Get number of loaded volume sets.
Definition gvl.c:105
int gvl_free_vol(geovol *fvl)
Free geovol struct.
Definition gvl.c:267
int gvl_file_free_datah(int id)
Free geovol_file structure for given handle.
Definition gvl_file.c:364
int gvl_file_newh(const char *name, IFLAG file_type)
Get handle for given file name and type.
Definition gvl_file.c:269
#define min(a, b)
#define max(a, b)
void G_zero(void *buf, int i)
Zero out a buffer, buf, of length i.
Definition zero.c:23