Line data Source code
1 : /*****************************************************************************
2 : *
3 : * This module has a number of additions and improvements over the original
4 : * implementation to be suitable for usage in GDAL HDF driver.
5 : *
6 : * Andrey Kiselev <dron@ak4719.spb.edu> is responsible for all the changes.
7 : ****************************************************************************/
8 :
9 : /*
10 : Copyright (C) 1996 Hughes and Applied Research Corporation
11 :
12 : Permission to use, modify, and distribute this software and its documentation
13 : for any purpose without fee is hereby granted, provided that the above
14 : copyright notice appear in all copies and that both that copyright notice and
15 : this permission notice appear in supporting documentation.
16 : */
17 : /*****************************************************************************
18 : REVISIONS:
19 :
20 : Aug 31, 1999 Abe Taaheri Changed memory allocation for utility strings to
21 : the size of UTLSTR_MAX_SIZE.
22 : Added error check for memory unavailability in
23 : several functions.
24 : Added check for NULL metabuf returned from
25 : EHmeta... functions. NULL pointer returned from
26 : EHmeta... functions indicate that memory could not
27 : be allocated for metabuf.
28 : Jun 27, 2000 Abe Taaheri Added support for EASE grid that uses
29 : Behrmann Cylinderical Equal Area (BCEA) projection
30 : Oct 23, 2000 Abe Taaheri Updated for ISINUS projection, so that both codes
31 : 31 and 99 can be used for this projection.
32 : Jan 15, 2003 Abe Taaheri Modified for generalization of EASE Grid.
33 :
34 : Jun 05, 2003 Bruce Beaumont / Abe Taaheri
35 :
36 : Fixed SQUARE definition.
37 : Added static projection number/name translation
38 : Added projection table lookup in GDdefproj.
39 : Removed projection table from GDdefproj
40 : Added projection table lookup in GDprojinfo
41 : Removed projection table from GDprojinfo
42 : Added cast for compcode in call to SDsetcompress
43 : in GDdeffield to avoid compiler errors
44 : Removed declaration for unused variable endptr
45 : in GDSDfldsrch
46 : Removed initialization code for unused variables
47 : in GDSDfldsrch
48 : Removed declarations for unused variables
49 : BCEA_scale, r0, s0, xMtr0, xMtr1, yMtr0,
50 : and yMtr1 in GDll2ij
51 : Removed initialization code for unused variables
52 : in GDll2ij
53 : Added code in GEO projection handling to allow
54 : map to span dateline in GDll2ij
55 : Changed "for each point" loop in GDll2ij to
56 : return -2147483648.0 for xVal and yVal if
57 : for_trans returned an error instead of
58 : returning an error to the caller
59 : (Note: MAXLONG is defined as 2147483647.0 in
60 : function cproj.c of GCTP)
61 : Added code in GDij2ll to use for_trans to
62 : translate the BCEA corner points from packed
63 : degrees to meters
64 : Removed declarations for unused variables
65 : BCEA_scale, r0, s0, xMtr, yMtr, epsilon,
66 : beta, qp_cea, kz_cea, eccen, eccen_sq,
67 : phi1, sinphi1, cosphi1, lon, lat, xcor,
68 : ycor, and nlatlon from GDij2ll
69 : Removed initialization code for unused variables
70 : in GDij2ll
71 : Added declarations for xMtr0, yMtr0, xMtr1, and
72 : yMtr1 in GDij2ll
73 : Added special-case code for BCEA
74 : Changed "for each point" loop in GDij2ll to
75 : return PGSd_GCT_IN_ERROR (1.0e51) for
76 : longitude and latitude values if inv_trans
77 : returned an error instead of return an error
78 : to the caller
79 : Removed declaration for unused variable ii in
80 : GDgetpixvalues
81 : Removed declaration for unused variable
82 : numTileDims in GDtileinfo
83 : Added error message and error return at the
84 : end of GDll2mm_cea
85 : Added return statement to GDll2mm_cea
86 : ******************************************************************************/
87 : #include "cpl_string.h"
88 : #include "stdio.h"
89 : #include "mfhdf.h"
90 : #include "hcomp.h"
91 : #include <math.h>
92 : #include "HdfEosDef.h"
93 : #include "hfile.h"
94 :
95 : #include "hdf4compat.h"
96 :
97 : #define GDIDOFFSET 4194304
98 : #define SQUARE(x) ((x) * (x)) /* x**2 */
99 :
100 :
101 : #define NGRID 200
102 : /* Grid Structure External Arrays */
103 : struct gridStructure
104 : {
105 : int32 active;
106 : int32 IDTable;
107 : int32 VIDTable[2];
108 : int32 fid;
109 : int32 nSDS;
110 : int32 *sdsID;
111 : int32 compcode;
112 : intn compparm[5];
113 : int32 tilecode;
114 : int32 tilerank;
115 : int32 tiledims[8];
116 : };
117 : static struct gridStructure GDXGrid[NGRID];
118 :
119 :
120 :
121 : #define NGRIDREGN 256
122 : struct gridRegion
123 : {
124 : int32 fid;
125 : int32 gridID;
126 : int32 xStart;
127 : int32 xCount;
128 : int32 yStart;
129 : int32 yCount;
130 : int32 somStart;
131 : int32 somCount;
132 : float64 upleftpt[2];
133 : float64 lowrightpt[2];
134 : int32 StartVertical[8];
135 : int32 StopVertical[8];
136 : char *DimNamePtr[8];
137 : };
138 : static struct gridRegion *GDXRegion[NGRIDREGN];
139 :
140 : /* define a macro for the string size of the utility strings and some dimension
141 : list strings. The value of 80 in the previous version of this code
142 : may not be enough in some cases. The length now is 512 which seems to
143 : be more than enough to hold larger strings. */
144 :
145 : #define UTLSTR_MAX_SIZE 512
146 :
147 : /* Static projection table */
148 : static const struct {
149 : int32 projcode;
150 : const char *projname;
151 : } Projections[] = {
152 : {GCTP_GEO, "GCTP_GEO"},
153 : {GCTP_UTM, "GCTP_UTM"},
154 : {GCTP_SPCS, "GCTP_SPCS"},
155 : {GCTP_ALBERS, "GCTP_ALBERS"},
156 : {GCTP_LAMCC, "GCTP_LAMCC"},
157 : {GCTP_MERCAT, "GCTP_MERCAT"},
158 : {GCTP_PS, "GCTP_PS"},
159 : {GCTP_POLYC, "GCTP_POLYC"},
160 : {GCTP_EQUIDC, "GCTP_EQUIDC"},
161 : {GCTP_TM, "GCTP_TM"},
162 : {GCTP_STEREO, "GCTP_STEREO"},
163 : {GCTP_LAMAZ, "GCTP_LAMAZ"},
164 : {GCTP_AZMEQD, "GCTP_AZMEQD"},
165 : {GCTP_GNOMON, "GCTP_GNOMON"},
166 : {GCTP_ORTHO, "GCTP_ORTHO"},
167 : {GCTP_GVNSP, "GCTP_GVNSP"},
168 : {GCTP_SNSOID, "GCTP_SNSOID"},
169 : {GCTP_EQRECT, "GCTP_EQRECT"},
170 : {GCTP_MILLER, "GCTP_MILLER"},
171 : {GCTP_VGRINT, "GCTP_VGRINT"},
172 : {GCTP_HOM, "GCTP_HOM"},
173 : {GCTP_ROBIN, "GCTP_ROBIN"},
174 : {GCTP_SOM, "GCTP_SOM"},
175 : {GCTP_ALASKA, "GCTP_ALASKA"},
176 : {GCTP_GOOD, "GCTP_GOOD"},
177 : {GCTP_MOLL, "GCTP_MOLL"},
178 : {GCTP_IMOLL, "GCTP_IMOLL"},
179 : {GCTP_HAMMER, "GCTP_HAMMER"},
180 : {GCTP_WAGIV, "GCTP_WAGIV"},
181 : {GCTP_WAGVII, "GCTP_WAGVII"},
182 : {GCTP_OBLEQA, "GCTP_OBLEQA"},
183 : {GCTP_ISINUS1, "GCTP_ISINUS1"},
184 : {GCTP_CEA, "GCTP_CEA"},
185 : {GCTP_BCEA, "GCTP_BCEA"},
186 : {GCTP_ISINUS, "GCTP_ISINUS"},
187 : {-1, NULL}
188 : };
189 :
190 : /* Grid Function Prototypes (internal routines) */
191 : static intn GDchkgdid(int32, const char *, int32 *, int32 *, int32 *);
192 : static intn GDSDfldsrch(int32, int32, const char *, int32 *, int32 *,
193 : int32 *, int32 *, int32 [], int32 *);
194 : static intn GDwrrdfield(int32, const char *, const char *,
195 : int32 [], int32 [], int32 [], VOIDP datbuf);
196 : static intn GDwrrdattr(int32, const char *, int32, int32, const char *, VOIDP);
197 : static intn GDwrrdtile(int32, const char *, const char *, int32 [], VOIDP);
198 :
199 : /*----------------------------------------------------------------------------|
200 : | BEGIN_PROLOG |
201 : | |
202 : | FUNCTION: GDopen |
203 : | |
204 : | DESCRIPTION: Opens or creates HDF file in order to create, read, or write |
205 : | a grid. |
206 : | |
207 : | |
208 : | Return Value Type Units Description |
209 : | ============ ====== ========= ===================================== |
210 : | fid int32 HDF-EOS file ID |
211 : | |
212 : | INPUTS: |
213 : | filename char Filename |
214 : | l_access intn HDF l_access code |
215 : | |
216 : | |
217 : | OUTPUTS: |
218 : | None |
219 : | |
220 : | NOTES: |
221 : | |
222 : | |
223 : | Date Programmer Description |
224 : | ====== ============ ================================================= |
225 : | Jun 96 Joel Gales Original Programmer |
226 : | |
227 : | END_PROLOG |
228 : -----------------------------------------------------------------------------*/
229 : int32
230 26 : GDopen(const char *filename, intn l_access)
231 :
232 : {
233 : int32 fid /* HDF-EOS file ID */ ;
234 :
235 : /* Call EHopen to perform file l_access */
236 : /* ---------------------------------- */
237 26 : fid = EHopen(filename, l_access);
238 :
239 26 : return (fid);
240 :
241 : }
242 :
243 :
244 : /*----------------------------------------------------------------------------|
245 : | BEGIN_PROLOG |
246 : | |
247 : | FUNCTION: GDattach |
248 : | |
249 : | DESCRIPTION: Attaches to an existing grid within the file. |
250 : | |
251 : | |
252 : | Return Value Type Units Description |
253 : | ============ ====== ========= ===================================== |
254 : | gridID int32 grid structure ID |
255 : | |
256 : | INPUTS: |
257 : | fid int32 HDF-EOS file id |
258 : | gridname char grid structure name |
259 : | |
260 : | |
261 : | OUTPUTS: |
262 : | None |
263 : | |
264 : | NOTES: |
265 : | |
266 : | |
267 : | Date Programmer Description |
268 : | ====== ============ ================================================= |
269 : | Jun 96 Joel Gales Original Programmer |
270 : | Sep 99 Abe Taaheri Modified test for memory allocation check when no |
271 : | SDSs are in the grid, NCR24147 |
272 : | |
273 : | END_PROLOG |
274 : -----------------------------------------------------------------------------*/
275 : int32
276 13 : GDattach(int32 fid, const char *gridname)
277 :
278 : {
279 : intn i; /* Loop index */
280 : intn j; /* Loop index */
281 13 : intn ngridopen = 0; /* # of grid structures open */
282 : intn status; /* routine return status variable */
283 :
284 : uint8 acs; /* Read/Write file l_access code */
285 :
286 : int32 HDFfid; /* HDF file id */
287 : int32 vgRef; /* Vgroup reference number */
288 : int32 vgid[3]; /* Vgroup ID array */
289 13 : int32 gridID = -1;/* HDF-EOS grid ID */
290 : int32 *tags; /* Pnt to Vgroup object tags array */
291 : int32 *refs; /* Pnt to Vgroup object refs array */
292 : int32 dum; /* dummy variable */
293 : int32 sdInterfaceID; /* HDF SDS interface ID */
294 : int32 nObjects; /* # of objects in Vgroup */
295 : int32 nSDS; /* SDS counter */
296 : int32 l_index; /* SDS l_index */
297 : int32 sdid; /* SDS object ID */
298 13 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
299 :
300 : char name[80]; /* Vgroup name */
301 : char class[80]; /* Vgroup class */
302 : char errbuf[256];/* Buffer for error message */
303 : char acsCode[1]; /* Read/Write l_access char: "r/w" */
304 :
305 :
306 : /* Check HDF-EOS file ID, get back HDF file ID and l_access code */
307 : /* ----------------------------------------------------------- */
308 13 : status = EHchkfid(fid, gridname, &HDFfid, &dum, &acs);
309 :
310 :
311 13 : if (status == 0)
312 : {
313 : /* Convert numeric l_access code to character */
314 : /* ---------------------------------------- */
315 :
316 13 : acsCode[0] = (acs == 1) ? 'w' : 'r';
317 :
318 : /* Determine number of grids currently opened */
319 : /* ------------------------------------------- */
320 2613 : for (i = 0; i < NGRID; i++)
321 : {
322 2600 : ngridopen += GDXGrid[i].active;
323 : }
324 :
325 :
326 : /* If room for more ... */
327 : /* -------------------- */
328 13 : if (ngridopen < NGRID)
329 : {
330 :
331 : /* Search Vgroups for Grid */
332 : /* ------------------------ */
333 13 : vgRef = -1;
334 :
335 : while (1)
336 : {
337 67 : vgRef = Vgetid(HDFfid, vgRef);
338 :
339 : /* If no more Vgroups then exist while loop */
340 : /* ---------------------------------------- */
341 67 : if (vgRef == -1)
342 : {
343 0 : break;
344 : }
345 :
346 : /* Get name and class of Vgroup */
347 : /* ---------------------------- */
348 67 : vgid[0] = Vattach(HDFfid, vgRef, "r");
349 67 : VgetnameSafe(vgid[0], name, sizeof(name));
350 : #if LIBVER_MAJOR == 4 && LIBVER_MINOR >= 4
351 : size_t sz = sizeof(class);
352 : Vgetclass(vgid[0], class, &sz);
353 : #else
354 67 : Vgetclass(vgid[0], class);
355 : #endif
356 :
357 : /*
358 : * If Vgroup with gridname and class GRID found, load tables
359 : */
360 :
361 67 : if (strcmp(name, gridname) == 0 &&
362 13 : strcmp(class, "GRID") == 0)
363 : {
364 : /* Attach to "Data Fields" and "Grid Attributes" Vgroups */
365 : /* ----------------------------------------------------- */
366 13 : tags = (int32 *) malloc(sizeof(int32) * 2);
367 13 : if(tags == NULL)
368 : {
369 0 : HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
370 0 : return(-1);
371 : }
372 13 : refs = (int32 *) malloc(sizeof(int32) * 2);
373 13 : if(refs == NULL)
374 : {
375 0 : HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
376 0 : free(tags);
377 0 : return(-1);
378 : }
379 13 : Vgettagrefs(vgid[0], tags, refs, 2);
380 13 : vgid[1] = Vattach(HDFfid, refs[0], acsCode);
381 13 : vgid[2] = Vattach(HDFfid, refs[1], acsCode);
382 13 : free(tags);
383 13 : free(refs);
384 :
385 :
386 : /* Setup External Arrays */
387 : /* --------------------- */
388 19 : for (i = 0; i < NGRID; i++)
389 : {
390 : /* Find empty entry in array */
391 : /* ------------------------- */
392 19 : if (GDXGrid[i].active == 0)
393 : {
394 : /*
395 : * Set gridID, Set grid entry active, Store root
396 : * Vgroup ID, Store sub Vgroup IDs, Store HDF-EOS
397 : * file ID
398 : */
399 13 : gridID = i + idOffset;
400 13 : GDXGrid[i].active = 1;
401 13 : GDXGrid[i].IDTable = vgid[0];
402 13 : GDXGrid[i].VIDTable[0] = vgid[1];
403 13 : GDXGrid[i].VIDTable[1] = vgid[2];
404 13 : GDXGrid[i].fid = fid;
405 13 : break;
406 : }
407 : }
408 :
409 : /* Get SDS interface ID */
410 : /* -------------------- */
411 13 : status = GDchkgdid(gridID, "GDattach", &dum,
412 : &sdInterfaceID, &dum);
413 13 : if( status < 0)
414 0 : return -1;
415 :
416 : /* Get # of entries within Data Vgroup & search for SDS */
417 : /* ---------------------------------------------------- */
418 13 : nObjects = Vntagrefs(vgid[1]);
419 :
420 13 : if (nObjects > 0)
421 : {
422 : /* Get tag and ref # for Data Vgroup objects */
423 : /* ----------------------------------------- */
424 5 : tags = (int32 *) malloc(sizeof(int32) * nObjects);
425 5 : if(tags == NULL)
426 : {
427 0 : HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
428 0 : return(-1);
429 : }
430 5 : refs = (int32 *) malloc(sizeof(int32) * nObjects);
431 5 : if(refs == NULL)
432 : {
433 0 : HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
434 0 : free(tags);
435 0 : return(-1);
436 : }
437 5 : Vgettagrefs(vgid[1], tags, refs, nObjects);
438 :
439 : /* Count number of SDS & allocate SDS ID array */
440 : /* ------------------------------------------- */
441 5 : nSDS = 0;
442 10 : for (j = 0; j < nObjects; j++)
443 : {
444 5 : if (tags[j] == DFTAG_NDG)
445 : {
446 5 : nSDS++;
447 : }
448 : }
449 5 : GDXGrid[i].sdsID = (int32 *) calloc(nSDS, 4);
450 5 : if(GDXGrid[i].sdsID == NULL && nSDS != 0)
451 : {
452 0 : HEpush(DFE_NOSPACE,"GDattach", __FILE__, __LINE__);
453 0 : free(tags);
454 0 : free(refs);
455 0 : return(-1);
456 : }
457 5 : nSDS = 0;
458 :
459 :
460 :
461 : /* Fill SDS ID array */
462 : /* ----------------- */
463 10 : for (j = 0; j < nObjects; j++)
464 : {
465 : /* If object is SDS then get id */
466 : /* ---------------------------- */
467 5 : if (tags[j] == DFTAG_NDG)
468 : {
469 5 : l_index = SDreftoindex(sdInterfaceID, refs[j]);
470 5 : sdid = SDselect(sdInterfaceID, l_index);
471 5 : GDXGrid[i].sdsID[nSDS] = sdid;
472 5 : nSDS++;
473 5 : GDXGrid[i].nSDS++;
474 : }
475 : }
476 5 : free(tags);
477 5 : free(refs);
478 : }
479 13 : break;
480 : }
481 :
482 : /* Detach Vgroup if not desired Grid */
483 : /* --------------------------------- */
484 54 : Vdetach(vgid[0]);
485 : }
486 :
487 : /* If Grid not found then set up error message */
488 : /* ------------------------------------------- */
489 13 : if (gridID == -1)
490 : {
491 0 : HEpush(DFE_RANGE, "GDattach", __FILE__, __LINE__);
492 0 : HEreport("Grid: \"%s\" does not exist within HDF file.\n",
493 : gridname);
494 : }
495 : }
496 : else
497 : {
498 : /* Too many files opened */
499 : /* --------------------- */
500 0 : gridID = -1;
501 0 : strcpy(errbuf,
502 : "No more than %d grids may be open simultaneously");
503 0 : strcat(errbuf, " (%s)");
504 0 : HEpush(DFE_DENIED, "GDattach", __FILE__, __LINE__);
505 0 : HEreport(errbuf, NGRID, gridname);
506 : }
507 :
508 : }
509 13 : return (gridID);
510 : }
511 :
512 :
513 : /*----------------------------------------------------------------------------|
514 : | BEGIN_PROLOG |
515 : | |
516 : | FUNCTION: GDchkgdid |
517 : | |
518 : | DESCRIPTION: |
519 : | |
520 : | |
521 : | Return Value Type Units Description |
522 : | ============ ====== ========= ===================================== |
523 : | status intn return status (0) SUCCEED, (-1) FAIL |
524 : | |
525 : | INPUTS: |
526 : | gridID int32 grid structure ID |
527 : | routname char Name of routine calling GDchkgdid |
528 : | |
529 : | OUTPUTS: |
530 : | fid int32 File ID |
531 : | sdInterfaceID int32 SDS interface ID |
532 : | gdVgrpID int32 grid Vgroup ID |
533 : | |
534 : | |
535 : | OUTPUTS: |
536 : | None |
537 : | |
538 : | NOTES: |
539 : | |
540 : | |
541 : | Date Programmer Description |
542 : | ====== ============ ================================================= |
543 : | Jun 96 Joel Gales Original Programmer |
544 : | |
545 : | END_PROLOG |
546 : -----------------------------------------------------------------------------*/
547 : static intn
548 179 : GDchkgdid(int32 gridID, const char *routname,
549 : int32 * fid, int32 * sdInterfaceID, int32 * gdVgrpID)
550 : {
551 179 : intn status = 0; /* routine return status variable */
552 : uint8 l_access; /* Read/Write l_access code */
553 : int32 gID; /* Grid ID - offset */
554 :
555 179 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
556 :
557 : static const char message1[] =
558 : "Invalid grid id: %d in routine \"%s\". ID must be >= %d and < %d.\n";
559 : static const char message2[] =
560 : "Grid id %d in routine \"%s\" not active.\n";
561 :
562 :
563 :
564 : /* Check for valid grid id */
565 :
566 179 : if (gridID < idOffset || gridID >= NGRID + idOffset)
567 : {
568 0 : status = -1;
569 0 : HEpush(DFE_RANGE, "GDchkgdid", __FILE__, __LINE__);
570 0 : HEreport(message1, gridID, routname, idOffset, NGRID + idOffset);
571 : }
572 : else
573 : {
574 :
575 : /* Compute "reduced" ID */
576 : /* -------------------- */
577 179 : gID = gridID % idOffset;
578 :
579 : /* Check for active grid ID */
580 : /* ------------------------ */
581 179 : if (GDXGrid[gID].active == 0)
582 : {
583 1 : status = -1;
584 1 : HEpush(DFE_GENAPP, "GDchkgdid", __FILE__, __LINE__);
585 1 : HEreport(message2, gridID, routname);
586 : }
587 : else
588 : {
589 :
590 : /* Get file & SDS ids and Grid key */
591 : /* -------------------------------- */
592 178 : status = EHchkfid(GDXGrid[gID].fid, " ",
593 : fid, sdInterfaceID, &l_access);
594 178 : *gdVgrpID = GDXGrid[gID].IDTable;
595 : }
596 : }
597 179 : return (status);
598 :
599 : }
600 :
601 :
602 : /*----------------------------------------------------------------------------|
603 : | BEGIN_PROLOG |
604 : | |
605 : | FUNCTION: GDdiminfo |
606 : | |
607 : | DESCRIPTION: Retrieve size of specified dimension. |
608 : | |
609 : | |
610 : | Return Value Type Units Description |
611 : | ============ ====== ========= ===================================== |
612 : | size int32 Size of dimension |
613 : | |
614 : | INPUTS: |
615 : | gridID int32 grid structure id |
616 : | dimname char Dimension name |
617 : | |
618 : | |
619 : | OUTPUTS: |
620 : | None |
621 : | |
622 : | NOTES: |
623 : | |
624 : | |
625 : | Date Programmer Description |
626 : | ====== ============ ================================================= |
627 : | Jun 96 Joel Gales Original Programmer |
628 : | Aug 96 Joel Gales Make metadata ODL compliant |
629 : | Jan 97 Joel Gales Check for metadata error status from EHgetmetavalue |
630 : | |
631 : | END_PROLOG |
632 : -----------------------------------------------------------------------------*/
633 : int32
634 4 : GDdiminfo(int32 gridID, const char *dimname)
635 :
636 : {
637 : intn status; /* routine return status variable */
638 :
639 : int32 fid; /* HDF-EOS file ID */
640 : int32 sdInterfaceID; /* HDF SDS interface ID */
641 : int32 gdVgrpID; /* Grid root Vgroup ID */
642 : int32 size; /* Dimension size */
643 4 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
644 :
645 :
646 : char *metabuf; /* Pointer to structural metadata (SM) */
647 : char *metaptrs[2];/* Pointers to begin and end of SM section */
648 : char gridname[80]; /* Grid Name */
649 : char *utlstr; /* Utility string */
650 :
651 : /* Allocate space for utility string */
652 : /* --------------------------------- */
653 4 : utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
654 4 : if(utlstr == NULL)
655 : {
656 0 : HEpush(DFE_NOSPACE,"GDdiminfo", __FILE__, __LINE__);
657 0 : return(-1);
658 : }
659 : /* Initialize return value */
660 : /* ----------------------- */
661 4 : size = -1;
662 :
663 :
664 : /* Check Grid ID */
665 : /* ------------- */
666 4 : status = GDchkgdid(gridID, "GDdiminfo", &fid, &sdInterfaceID, &gdVgrpID);
667 :
668 :
669 4 : if (status == 0)
670 : {
671 : /* Get grid name */
672 : /* ------------- */
673 4 : int gID = gridID % idOffset;
674 4 : if (gID >= NGRID)
675 : {
676 0 : free(utlstr);
677 0 : return -1;
678 : }
679 4 : VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
680 :
681 :
682 : /* Get pointers to "Dimension" section within SM */
683 : /* --------------------------------------------- */
684 4 : metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
685 : "Dimension", metaptrs);
686 :
687 4 : if(metabuf == NULL)
688 : {
689 0 : free(utlstr);
690 0 : return(-1);
691 : }
692 :
693 : /* Search for dimension name (surrounded by quotes) */
694 : /* ------------------------------------------------ */
695 4 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "\"", dimname, "\"\n");
696 4 : metaptrs[0] = strstr(metaptrs[0], utlstr);
697 :
698 : /*
699 : * If dimension found within grid structure then get dimension value
700 : */
701 4 : if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
702 : {
703 : /* Set endptr at end of dimension definition entry */
704 : /* ----------------------------------------------- */
705 4 : metaptrs[1] = strstr(metaptrs[0], "\t\t\tEND_OBJECT");
706 :
707 4 : status = EHgetmetavalue(metaptrs, "Size", utlstr);
708 :
709 4 : if (status == 0)
710 : {
711 4 : size = atoi(utlstr);
712 : }
713 : else
714 : {
715 0 : HEpush(DFE_GENAPP, "GDdiminfo", __FILE__, __LINE__);
716 0 : HEreport("\"Size\" string not found in metadata.\n");
717 : }
718 : }
719 : else
720 : {
721 0 : HEpush(DFE_GENAPP, "GDdiminfo", __FILE__, __LINE__);
722 0 : HEreport("Dimension \"%s\" not found.\n", dimname);
723 : }
724 :
725 4 : free(metabuf);
726 : }
727 4 : free(utlstr);
728 4 : return (size);
729 : }
730 :
731 :
732 :
733 :
734 :
735 : /*----------------------------------------------------------------------------|
736 : | BEGIN_PROLOG |
737 : | |
738 : | FUNCTION: GDgridinfo |
739 : | |
740 : | DESCRIPTION: Returns xdim, ydim and location of upper left and lower |
741 : | right corners, in meters. |
742 : | |
743 : | |
744 : | Return Value Type Units Description |
745 : | ============ ====== ========= ===================================== |
746 : | status intn return status (0) SUCCEED, (-1) FAIL |
747 : | |
748 : | INPUTS: |
749 : | fid int32 File ID |
750 : | gridname char Grid structure name |
751 : | |
752 : | OUTPUTS: |
753 : | xdimsize int32 Number of columns in grid |
754 : | ydimsize int32 Number of rows in grid |
755 : | upleftpt float64 Location (m/deg) of upper left corner |
756 : | lowrightpt float64 Location (m/deg) of lower right corner |
757 : | |
758 : | NOTES: |
759 : | |
760 : | |
761 : | Date Programmer Description |
762 : | ====== ============ ================================================= |
763 : | Jun 96 Joel Gales Original Programmer |
764 : | Jan 97 Joel Gales Check for metadata error status from EHgetmetavalue |
765 : | |
766 : | END_PROLOG |
767 : -----------------------------------------------------------------------------*/
768 : intn
769 11 : GDgridinfo(int32 gridID, int32 * xdimsize, int32 * ydimsize,
770 : float64 upleftpt[], float64 lowrightpt[])
771 :
772 : {
773 11 : intn status = 0; /* routine return status variable */
774 11 : intn statmeta = 0; /* EHgetmetavalue return status */
775 :
776 : int32 fid; /* HDF-EOS file ID */
777 : int32 sdInterfaceID; /* HDF SDS interface ID */
778 : int32 gdVgrpID; /* Grid root Vgroup ID */
779 11 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
780 :
781 :
782 : char *metabuf; /* Pointer to structural metadata (SM) */
783 : char *metaptrs[2];/* Pointers to begin and end of SM section */
784 : char gridname[80]; /* Grid Name */
785 : char *utlstr; /* Utility string */
786 :
787 : /* Allocate space for utility string */
788 : /* --------------------------------- */
789 11 : utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
790 11 : if(utlstr == NULL)
791 : {
792 0 : HEpush(DFE_NOSPACE,"GDgridinfo", __FILE__, __LINE__);
793 0 : return(-1);
794 : }
795 : /* Check Grid ID */
796 : /* ------------- */
797 11 : status = GDchkgdid(gridID, "GDgridinfo", &fid, &sdInterfaceID, &gdVgrpID);
798 :
799 11 : if (status == 0)
800 : {
801 : /* Get grid name */
802 : /* ------------- */
803 11 : int gID = gridID % idOffset;
804 11 : if (gID >= NGRID)
805 : {
806 0 : free(utlstr);
807 0 : return -1;
808 : }
809 11 : VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
810 :
811 :
812 : /* Get pointers to grid structure section within SM */
813 : /* ------------------------------------------------ */
814 11 : metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
815 : NULL, metaptrs);
816 :
817 11 : if(metabuf == NULL)
818 : {
819 0 : free(utlstr);
820 0 : return(-1);
821 : }
822 :
823 :
824 : /* Get xdimsize if requested */
825 : /* ------------------------- */
826 11 : if (xdimsize != NULL)
827 : {
828 11 : statmeta = EHgetmetavalue(metaptrs, "XDim", utlstr);
829 11 : if (statmeta == 0)
830 : {
831 11 : *xdimsize = atoi(utlstr);
832 : }
833 : else
834 : {
835 0 : status = -1;
836 0 : HEpush(DFE_GENAPP, "GDgridinfo", __FILE__, __LINE__);
837 0 : HEreport("\"XDim\" string not found in metadata.\n");
838 : }
839 : }
840 :
841 :
842 : /* Get ydimsize if requested */
843 : /* ------------------------- */
844 11 : if (ydimsize != NULL)
845 : {
846 11 : statmeta = EHgetmetavalue(metaptrs, "YDim", utlstr);
847 11 : if (statmeta == 0)
848 : {
849 11 : *ydimsize = atoi(utlstr);
850 : }
851 : else
852 : {
853 0 : status = -1;
854 0 : HEpush(DFE_GENAPP, "GDgridinfo", __FILE__, __LINE__);
855 0 : HEreport("\"YDim\" string not found in metadata.\n");
856 : }
857 : }
858 :
859 :
860 : /* Get upleftpt if requested */
861 : /* ------------------------- */
862 11 : if (upleftpt != NULL)
863 : {
864 4 : statmeta = EHgetmetavalue(metaptrs, "UpperLeftPointMtrs", utlstr);
865 4 : if (statmeta == 0)
866 : {
867 : /* If value is "DEFAULT" then return zeros */
868 : /* --------------------------------------- */
869 4 : if (strcmp(utlstr, "DEFAULT") == 0)
870 : {
871 0 : upleftpt[0] = 0;
872 0 : upleftpt[1] = 0;
873 : }
874 : else
875 : {
876 4 : sscanf(utlstr, "(%lf,%lf)",
877 : &upleftpt[0], &upleftpt[1]);
878 : }
879 : }
880 : else
881 : {
882 0 : status = -1;
883 0 : HEpush(DFE_GENAPP, "GDgridinfo", __FILE__, __LINE__);
884 0 : HEreport(
885 : "\"UpperLeftPointMtrs\" string not found in metadata.\n");
886 : }
887 :
888 : }
889 :
890 : /* Get lowrightpt if requested */
891 : /* --------------------------- */
892 11 : if (lowrightpt != NULL)
893 : {
894 4 : statmeta = EHgetmetavalue(metaptrs, "LowerRightMtrs", utlstr);
895 4 : if (statmeta == 0)
896 : {
897 : /* If value is "DEFAULT" then return zeros */
898 4 : if (strcmp(utlstr, "DEFAULT") == 0)
899 : {
900 0 : lowrightpt[0] = 0;
901 0 : lowrightpt[1] = 0;
902 : }
903 : else
904 : {
905 4 : sscanf(utlstr, "(%lf,%lf)",
906 : &lowrightpt[0], &lowrightpt[1]);
907 : }
908 : }
909 : else
910 : {
911 0 : status = -1;
912 0 : HEpush(DFE_GENAPP, "GDgridinfo", __FILE__, __LINE__);
913 0 : HEreport(
914 : "\"LowerRightMtrs\" string not found in metadata.\n");
915 : }
916 : }
917 :
918 11 : free(metabuf);
919 : }
920 11 : free(utlstr);
921 11 : return (status);
922 : }
923 :
924 :
925 :
926 :
927 :
928 :
929 :
930 : /*----------------------------------------------------------------------------|
931 : | BEGIN_PROLOG |
932 : | |
933 : | FUNCTION: GDprojinfo |
934 : | |
935 : | DESCRIPTION: Returns GCTP projection code, zone code, spheroid code |
936 : | and projection parameters. |
937 : | |
938 : | |
939 : | Return Value Type Units Description |
940 : | ============ ====== ========= ===================================== |
941 : | status intn return status (0) SUCCEED, (-1) FAIL |
942 : | |
943 : | INPUTS: |
944 : | gridID int32 Grid structure ID |
945 : | |
946 : | OUTPUTS: |
947 : | projcode int32 GCTP projection code |
948 : | zonecode int32 UTM zone code |
949 : | spherecode int32 GCTP spheroid code |
950 : | projparm float64 Projection parameters |
951 : | |
952 : | NOTES: |
953 : | |
954 : | |
955 : | Date Programmer Description |
956 : | ====== ============ ================================================= |
957 : | Jun 96 Joel Gales Original Programmer |
958 : | Oct 96 Joel Gales Add check for no projection code |
959 : | Jan 97 Joel Gales Check for metadata error status from EHgetmetavalue |
960 : | Jun 00 Abe Taaheri Added support for EASE grid |
961 : | |
962 : | END_PROLOG |
963 : -----------------------------------------------------------------------------*/
964 : intn
965 5 : GDprojinfo(int32 gridID, int32 * projcode, int32 * zonecode,
966 : int32 * spherecode, float64 projparm[])
967 :
968 : {
969 : intn i; /* Loop index */
970 : intn projx; /* Loop index */
971 5 : intn status = 0; /* routine return status variable */
972 5 : intn statmeta = 0; /* EHgetmetavalue return status */
973 :
974 : int32 fid; /* HDF-EOS file ID */
975 : int32 sdInterfaceID; /* HDF SDS interface ID */
976 : int32 gdVgrpID; /* Grid root Vgroup ID */
977 5 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
978 :
979 :
980 : char *metabuf; /* Pointer to structural metadata (SM) */
981 : char *metaptrs[2];/* Pointers to begin and end of SM section */
982 : char gridname[80]; /* Grid Name */
983 : char *utlstr; /* Utility string */
984 : char fmt[96]; /* Format String */
985 :
986 : /* Allocate space for utility string */
987 : /* --------------------------------- */
988 5 : utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
989 5 : if(utlstr == NULL)
990 : {
991 0 : HEpush(DFE_NOSPACE,"GDprojinfo", __FILE__, __LINE__);
992 0 : return(-1);
993 : }
994 :
995 : /* Check Grid ID */
996 : /* ------------- */
997 5 : status = GDchkgdid(gridID, "GDprojinfo", &fid, &sdInterfaceID, &gdVgrpID);
998 :
999 5 : if (status == 0)
1000 : {
1001 : /* Get grid name */
1002 : /* ------------- */
1003 5 : int gID = gridID % idOffset;
1004 5 : if (gID >= NGRID)
1005 : {
1006 0 : free(utlstr);
1007 0 : return -1;
1008 : }
1009 :
1010 5 : VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
1011 :
1012 :
1013 : /* Get pointers to grid structure section within SM */
1014 : /* ------------------------------------------------ */
1015 5 : metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
1016 : NULL, metaptrs);
1017 :
1018 5 : if(metabuf == NULL)
1019 : {
1020 0 : free(utlstr);
1021 0 : return(-1);
1022 : }
1023 :
1024 :
1025 : /* Get projcode if requested */
1026 : /* ------------------------- */
1027 5 : if (projcode != NULL)
1028 : {
1029 5 : *projcode = -1;
1030 :
1031 5 : statmeta = EHgetmetavalue(metaptrs, "Projection", utlstr);
1032 5 : if (statmeta == 0)
1033 : {
1034 : /* Loop through projection codes until found */
1035 : /* ----------------------------------------- */
1036 5 : for (projx = 0; Projections[projx].projcode != -1; projx++)
1037 5 : if (strcmp(utlstr, Projections[projx].projname) == 0)
1038 5 : break;
1039 5 : if (Projections[projx].projname != NULL)
1040 5 : *projcode = Projections[projx].projcode;
1041 : }
1042 : else
1043 : {
1044 0 : status = -1;
1045 0 : HEpush(DFE_GENAPP, "GDprojinfo", __FILE__, __LINE__);
1046 0 : HEreport("Projection Code not defined for \"%s\".\n",
1047 : gridname);
1048 :
1049 0 : if (projparm != NULL)
1050 : {
1051 0 : for (i = 0; i < 13; i++)
1052 : {
1053 0 : projparm[i] = -1;
1054 : }
1055 : }
1056 : }
1057 : }
1058 :
1059 :
1060 : /* Get zonecode if requested */
1061 : /* ------------------------- */
1062 5 : if (projcode && zonecode != NULL)
1063 : {
1064 5 : *zonecode = -1;
1065 :
1066 :
1067 : /* Zone code only relevant for UTM and State Code projections */
1068 : /* ---------------------------------------------------------- */
1069 5 : if (*projcode == GCTP_UTM || *projcode == GCTP_SPCS)
1070 : {
1071 0 : statmeta = EHgetmetavalue(metaptrs, "ZoneCode", utlstr);
1072 0 : if (statmeta == 0)
1073 : {
1074 0 : *zonecode = atoi(utlstr);
1075 : }
1076 : else
1077 : {
1078 0 : status = -1;
1079 0 : HEpush(DFE_GENAPP, "GDprojinfo", __FILE__, __LINE__);
1080 0 : HEreport("Zone Code not defined for \"%s\".\n",
1081 : gridname);
1082 : }
1083 : }
1084 : }
1085 :
1086 :
1087 : /* Get projection parameters if requested */
1088 : /* -------------------------------------- */
1089 5 : if (projcode && projparm != NULL)
1090 : {
1091 :
1092 : /*
1093 : * Note: No projection parameters for GEO, UTM, and State Code
1094 : * projections
1095 : */
1096 5 : if (*projcode == GCTP_GEO || *projcode == GCTP_UTM ||
1097 0 : *projcode == GCTP_SPCS)
1098 : {
1099 70 : for (i = 0; i < 13; i++)
1100 : {
1101 65 : projparm[i] = 0.0;
1102 : }
1103 :
1104 : }
1105 : else
1106 : {
1107 0 : statmeta = EHgetmetavalue(metaptrs, "ProjParams", utlstr);
1108 :
1109 0 : if (statmeta == 0)
1110 : {
1111 :
1112 : /* Build format string to read projection parameters */
1113 : /* ------------------------------------------------- */
1114 0 : strcpy(fmt, "%lf,");
1115 0 : for (i = 1; i <= 11; i++)
1116 0 : strcat(fmt, "%lf,");
1117 0 : strcat(fmt, "%lf");
1118 :
1119 :
1120 : /* Read parameters from numeric list */
1121 : /* --------------------------------- */
1122 0 : sscanf(&utlstr[1], fmt,
1123 : &projparm[0], &projparm[1],
1124 : &projparm[2], &projparm[3],
1125 : &projparm[4], &projparm[5],
1126 : &projparm[6], &projparm[7],
1127 : &projparm[8], &projparm[9],
1128 : &projparm[10], &projparm[11],
1129 : &projparm[12]);
1130 : }
1131 : else
1132 : {
1133 0 : status = -1;
1134 0 : HEpush(DFE_GENAPP, "GDprojinfo", __FILE__, __LINE__);
1135 0 : HEreport("Projection parameters not defined for \"%s\".\n",
1136 : gridname);
1137 :
1138 : }
1139 : }
1140 : }
1141 :
1142 :
1143 : /* Get spherecode if requested */
1144 : /* --------------------------- */
1145 5 : if (projcode && spherecode != NULL)
1146 : {
1147 5 : *spherecode = 0;
1148 :
1149 : /* Note: Spherecode not defined for GEO projection */
1150 : /* ----------------------------------------------- */
1151 5 : if ((*projcode != GCTP_GEO))
1152 : {
1153 0 : EHgetmetavalue(metaptrs, "SphereCode", utlstr);
1154 0 : if (statmeta == 0)
1155 : {
1156 0 : *spherecode = atoi(utlstr);
1157 : }
1158 : }
1159 : }
1160 5 : free(metabuf);
1161 :
1162 : }
1163 5 : free(utlstr);
1164 5 : return (status);
1165 : }
1166 :
1167 :
1168 : /*----------------------------------------------------------------------------|
1169 : | BEGIN_PROLOG |
1170 : | |
1171 : | FUNCTION: GDfieldinfo |
1172 : | |
1173 : | DESCRIPTION: Retrieve information about a specific geolocation or data |
1174 : | field in the grid. |
1175 : | |
1176 : | |
1177 : | Return Value Type Units Description |
1178 : | ============ ====== ========= ===================================== |
1179 : | status intn return status (0) SUCCEED, (-1) FAIL |
1180 : | |
1181 : | INPUTS: |
1182 : | gridID int32 grid structure id |
1183 : | fieldname char name of field |
1184 : | |
1185 : | |
1186 : | OUTPUTS: |
1187 : | rank int32 rank of field (# of dims) |
1188 : | dims int32 field dimensions |
1189 : | numbertype int32 field number type |
1190 : | dimlist char field dimension list |
1191 : | |
1192 : | |
1193 : | OUTPUTS: |
1194 : | None |
1195 : | |
1196 : | NOTES: |
1197 : | |
1198 : | |
1199 : | Date Programmer Description |
1200 : | ====== ============ ================================================= |
1201 : | Jun 96 Joel Gales Original Programmer |
1202 : | Aug 96 Joel Gales Make metadata ODL compliant |
1203 : | Jan 97 Joel Gales Check for metadata error status from EHgetmetavalue |
1204 : | Feb 99 Abe Taaheri Changed memcpy to memmove to avoid overlapping |
1205 : | problem when copying strings |
1206 : | |
1207 : | END_PROLOG |
1208 : -----------------------------------------------------------------------------*/
1209 : intn
1210 107 : GDfieldinfo(int32 gridID, const char *fieldname, int32 * rank, int32 dims[],
1211 : int32 * numbertype, char dimlist[HDFE_DIMBUFSIZE+1])
1212 :
1213 : {
1214 : intn i; /* Loop index */
1215 : intn status; /* routine return status variable */
1216 107 : intn statmeta = 0; /* EHgetmetavalue return status */
1217 :
1218 : int32 fid; /* HDF-EOS file ID */
1219 : int32 sdInterfaceID; /* HDF SDS interface ID */
1220 107 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
1221 107 : int32 ndims = 0; /* Number of dimensions */
1222 : int32 slen[8]; /* Length of each entry in parsed string */
1223 : int32 dum; /* Dummy variable */
1224 107 : int32 xdim = 0; /* X dim size */
1225 107 : int32 ydim = 0; /* Y dim size */
1226 : int32 sdid; /* SDS id */
1227 :
1228 : char *metabuf; /* Pointer to structural metadata (SM) */
1229 : char *metaptrs[2]; /* Pointers to begin and end of SM section */
1230 : char gridname[80]; /* Grid Name */
1231 : char *utlstr; /* Utility string */
1232 : char *ptr[8]; /* String pointers for parsed string */
1233 : char dimstr[64]; /* Individual dimension entry string */
1234 :
1235 :
1236 : /* Allocate space for utility string */
1237 : /* --------------------------------- */
1238 107 : utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
1239 107 : if(utlstr == NULL)
1240 : {
1241 0 : HEpush(DFE_NOSPACE,"GDfieldinfo", __FILE__, __LINE__);
1242 0 : return(-1);
1243 : }
1244 107 : *rank = -1;
1245 107 : *numbertype = -1;
1246 :
1247 107 : status = GDchkgdid(gridID, "GDfieldinfo", &fid, &sdInterfaceID, &dum);
1248 :
1249 107 : if (status == 0)
1250 : {
1251 107 : int gID = gridID % idOffset;
1252 107 : if (gID >= NGRID)
1253 : {
1254 0 : free(utlstr);
1255 0 : return -1;
1256 : }
1257 107 : VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
1258 :
1259 107 : metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
1260 : "DataField", metaptrs);
1261 107 : if(metabuf == NULL)
1262 : {
1263 0 : free(utlstr);
1264 0 : return(-1);
1265 : }
1266 :
1267 107 : if (!metaptrs[0])
1268 : {
1269 0 : free(utlstr);
1270 0 : free(metabuf);
1271 0 : return -1;
1272 : }
1273 :
1274 : /* Search for field */
1275 107 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "\"", fieldname, "\"\n");
1276 107 : metaptrs[0] = strstr(metaptrs[0], utlstr);
1277 :
1278 : /* If field found ... */
1279 107 : if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
1280 : {
1281 :
1282 : /* Set endptr at end of dimension definition entry */
1283 7 : metaptrs[1] = strstr(metaptrs[0], "\t\t\tEND_OBJECT");
1284 :
1285 : /* Get DataType string */
1286 7 : statmeta = EHgetmetavalue(metaptrs, "DataType", utlstr);
1287 :
1288 : /* Convert to numbertype code */
1289 7 : if (statmeta == 0)
1290 7 : *numbertype = EHnumstr(utlstr);
1291 : else
1292 : {
1293 0 : status = -1;
1294 0 : HEpush(DFE_GENAPP, "GDfieldinfo", __FILE__, __LINE__);
1295 0 : HEreport("\"DataType\" string not found in metadata.\n");
1296 : }
1297 :
1298 : /*
1299 : * Get DimList string and trim off leading and trailing parens
1300 : * "()"
1301 : */
1302 7 : statmeta = EHgetmetavalue(metaptrs, "DimList", utlstr);
1303 :
1304 7 : if (statmeta == 0)
1305 : {
1306 7 : const size_t len = strlen(utlstr);
1307 7 : if (len >= 2 && utlstr[0] == '(' && utlstr[len-1] == ')')
1308 : {
1309 4 : memmove(utlstr, utlstr + 1, len - 2);
1310 4 : utlstr[len - 2] = '\0';
1311 : }
1312 :
1313 : /* Parse trimmed DimList string and get rank */
1314 7 : ndims = EHparsestr(utlstr, ',', ptr, CPL_ARRAYSIZE(ptr), slen, CPL_ARRAYSIZE(slen));
1315 7 : if (ndims < 0)
1316 : {
1317 0 : status = -1;
1318 0 : HEpush(DFE_NOSPACE, "GDfieldinfo", __FILE__, __LINE__);
1319 : }
1320 7 : *rank = ndims;
1321 : }
1322 : else
1323 : {
1324 0 : status = -1;
1325 0 : HEpush(DFE_GENAPP, "GDfieldinfo", __FILE__, __LINE__);
1326 0 : HEreport("\"DimList\" string not found in metadata.\n");
1327 : }
1328 :
1329 :
1330 7 : if (status == 0)
1331 : {
1332 7 : status = GDgridinfo(gridID, &xdim, &ydim, NULL, NULL);
1333 :
1334 7 : dims[0] = -1;
1335 15 : for (i = 0; i < ndims; i++)
1336 : {
1337 8 : memcpy(dimstr, ptr[i] + 1, slen[i] - 2);
1338 8 : dimstr[slen[i] - 2] = 0;
1339 :
1340 8 : if (strcmp(dimstr, "XDim") == 0)
1341 : {
1342 0 : dims[i] = xdim;
1343 : }
1344 8 : else if (strcmp(dimstr, "YDim") == 0)
1345 : {
1346 4 : dims[i] = ydim;
1347 : }
1348 : else
1349 : {
1350 4 : dims[i] = GDdiminfo(gridID, dimstr);
1351 : }
1352 :
1353 :
1354 8 : if (dimlist != NULL)
1355 : {
1356 4 : if (i == 0)
1357 : {
1358 2 : dimlist[0] = 0;
1359 : }
1360 :
1361 4 : if (i > 0)
1362 : {
1363 2 : if( strlen(dimlist) + 1 > HDFE_DIMBUFSIZE )
1364 : {
1365 0 : free(metabuf);
1366 0 : free(utlstr);
1367 0 : return -1;
1368 : }
1369 2 : strcat(dimlist, ",");
1370 : }
1371 4 : if( strlen(dimlist) + strlen(dimstr) > HDFE_DIMBUFSIZE )
1372 : {
1373 0 : free(metabuf);
1374 0 : free(utlstr);
1375 0 : return -1;
1376 : }
1377 4 : strcat(dimlist, dimstr);
1378 : }
1379 : }
1380 :
1381 :
1382 7 : if (dims[0] == 0)
1383 : {
1384 4 : status = GDSDfldsrch(gridID, sdInterfaceID, fieldname,
1385 : &sdid, &dum, &dum, &dum, dims,
1386 : &dum);
1387 : }
1388 : }
1389 : }
1390 :
1391 107 : free(metabuf);
1392 : }
1393 :
1394 107 : if (*rank == -1)
1395 : {
1396 100 : status = -1;
1397 :
1398 100 : HEpush(DFE_GENAPP, "GDfieldinfo", __FILE__, __LINE__);
1399 100 : HEreport("Fieldname \"%s\" not found.\n", fieldname);
1400 : }
1401 107 : free(utlstr);
1402 107 : return (status);
1403 : }
1404 :
1405 :
1406 :
1407 : /*----------------------------------------------------------------------------|
1408 : | BEGIN_PROLOG |
1409 : | |
1410 : | FUNCTION: GDSDfldsrch |
1411 : | |
1412 : | DESCRIPTION: Retrieves information from SDS fields |
1413 : | |
1414 : | |
1415 : | Return Value Type Units Description |
1416 : | ============ ====== ========= ===================================== |
1417 : | status intn return status (0) SUCCEED, (-1) FAIL |
1418 : | |
1419 : | INPUTS: |
1420 : | gridID int32 grid structure ID |
1421 : | sdInterfaceID int32 SD interface ID |
1422 : | fieldname char field name |
1423 : | |
1424 : | |
1425 : | OUTPUTS: |
1426 : | sdid int32 SD element ID |
1427 : | rankSDS int32 Rank of SDS |
1428 : | rankFld int32 True rank of field (merging) |
1429 : | offset int32 Offset of field within merged field |
1430 : | dims int32 Dimensions of field |
1431 : | solo int32 Solo field flag |
1432 : | |
1433 : | NOTES: |
1434 : | |
1435 : | |
1436 : | Date Programmer Description |
1437 : | ====== ============ ================================================= |
1438 : | Jun 96 Joel Gales Original Programmer |
1439 : | Aug 96 Joel Gales Make metadata ODL compliant |
1440 : | |
1441 : | END_PROLOG |
1442 : -----------------------------------------------------------------------------*/
1443 : static intn
1444 10 : GDSDfldsrch(int32 gridID, int32 sdInterfaceID, const char *fieldname,
1445 : int32 * sdid, int32 * rankSDS, int32 * rankFld, int32 * offset,
1446 : int32 dims[], int32 * solo)
1447 : {
1448 : intn i; /* Loop index */
1449 10 : intn status = -1;/* routine return status variable */
1450 :
1451 : int32 gID; /* GridID - offset */
1452 10 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
1453 : int32 dum; /* Dummy variable */
1454 : int32 dums[128]; /* Dummy array */
1455 : int32 attrIndex; /* Attribute l_index */
1456 :
1457 : char name[2048]; /* Merged-Field Names */
1458 : char gridname[80]; /* Grid Name */
1459 : char *utlstr;/* Utility string */
1460 : char *metabuf; /* Pointer to structural metadata (SM) */
1461 : char *metaptrs[2];/* Pointers to begin and end of SM section */
1462 : #ifdef broken_logic
1463 : char *oldmetaptr; /* Pointer within SM section */
1464 : char *metaptr; /* Pointer within SM section */
1465 : #endif
1466 :
1467 : /* Allocate space for utility string */
1468 : /* --------------------------------- */
1469 10 : utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
1470 10 : if(utlstr == NULL)
1471 : {
1472 0 : HEpush(DFE_NOSPACE,"GDSDfldsrch", __FILE__, __LINE__);
1473 0 : return(-1);
1474 : }
1475 : /* Set solo flag to 0 (no) */
1476 : /* ----------------------- */
1477 10 : *solo = 0;
1478 :
1479 :
1480 : /* Compute "reduced" grid ID */
1481 : /* ------------------------- */
1482 10 : gID = gridID % idOffset;
1483 10 : if (gID >= NGRID)
1484 : {
1485 0 : free(utlstr);
1486 0 : return -1;
1487 : }
1488 :
1489 : /* Loop through all SDSs in grid */
1490 : /* ----------------------------- */
1491 15 : for (i = 0; i < GDXGrid[gID].nSDS; i++)
1492 : {
1493 : /* If active SDS ... */
1494 : /* ----------------- */
1495 5 : if (GDXGrid[gID].sdsID[i] != 0)
1496 : {
1497 : /* Get SDS ID, name, rankSDS, and dimensions */
1498 : /* ----------------------------------------- */
1499 5 : *sdid = GDXGrid[gID].sdsID[i];
1500 5 : SDgetinfo(*sdid, name, rankSDS, dims, &dum, &dum);
1501 5 : *rankFld = *rankSDS;
1502 :
1503 :
1504 : /* If merged field ... */
1505 : /* ------------------- */
1506 5 : if (strstr(name, "MRGFLD_") == &name[0])
1507 : {
1508 : /* Get grid name */
1509 : /* ------------- */
1510 5 : VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
1511 :
1512 :
1513 : /* Get pointers to "MergedFields" section within SM */
1514 : /* ------------------------------------------------ */
1515 5 : metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
1516 : "MergedFields", metaptrs);
1517 5 : if(metabuf == NULL)
1518 : {
1519 0 : free(utlstr);
1520 0 : return(-1);
1521 : }
1522 :
1523 : #ifdef broken_logic
1524 : /* Initialize metaptr to beg. of section */
1525 : /* ------------------------------------- */
1526 : metaptr = metaptrs[0];
1527 :
1528 :
1529 : /* Store metaptr in order to recover */
1530 : /* --------------------------------- */
1531 : oldmetaptr = metaptr;
1532 :
1533 :
1534 : /* Search for Merged field name */
1535 : /* ---------------------------- */
1536 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "MergedFieldName=\"",
1537 : name, "\"\n");
1538 : metaptr = strstr(metaptr, utlstr);
1539 :
1540 :
1541 : /* If not found check for old metadata */
1542 : /* ----------------------------------- */
1543 : if (metaptr == NULL)
1544 : {
1545 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "OBJECT=\"", name, "\"\n");
1546 : metaptr = strstr(oldmetaptr, utlstr);
1547 : }
1548 : #endif
1549 :
1550 : /* Get field list and strip off leading and trailing quotes */
1551 : /* -------------------------------------------------------- */
1552 5 : if (EHgetmetavalue(metaptrs, "FieldList", name) == 0)
1553 : {
1554 5 : const size_t len = strlen(name);
1555 5 : if (len >= 2 && name[0] == '"' && name[len-1] == '"')
1556 : {
1557 0 : memmove(name, name + 1, strlen(name) - 2);
1558 0 : name[strlen(name) - 2] = 0;
1559 : }
1560 : }
1561 : else
1562 : {
1563 0 : name[0] = '\0';
1564 : }
1565 :
1566 : /* Search for desired field within merged field list */
1567 : /* ------------------------------------------------- */
1568 5 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s%s", "\"", fieldname, "\"");
1569 5 : dum = EHstrwithin(utlstr, name, ',');
1570 :
1571 5 : free(metabuf);
1572 : }
1573 : else
1574 : {
1575 : /* If solo (unmerged) check if SDS name matches fieldname */
1576 : /* ------------------------------------------------------ */
1577 0 : dum = EHstrwithin(fieldname, name, ',');
1578 0 : if (dum != -1)
1579 : {
1580 0 : *solo = 1;
1581 0 : *offset = 0;
1582 : }
1583 : }
1584 :
1585 :
1586 :
1587 : /* If field found ... */
1588 : /* ------------------ */
1589 5 : if (dum != -1)
1590 : {
1591 0 : status = 0;
1592 :
1593 : /* If merged field ... */
1594 : /* ------------------- */
1595 0 : if (*solo == 0)
1596 : {
1597 : /* Get "Field Offsets" SDS attribute l_index */
1598 : /* --------------------------------------- */
1599 0 : attrIndex = SDfindattr(*sdid, "Field Offsets");
1600 :
1601 : /*
1602 : * If attribute exists then get offset of desired field
1603 : * within merged field
1604 : */
1605 0 : if (attrIndex != -1)
1606 : {
1607 0 : SDreadattr(*sdid, attrIndex, (VOIDP) dums);
1608 0 : *offset = dums[dum];
1609 : }
1610 :
1611 :
1612 : /* Get "Field Dims" SDS attribute l_index */
1613 : /* ------------------------------------ */
1614 0 : attrIndex = SDfindattr(*sdid, "Field Dims");
1615 :
1616 : /*
1617 : * If attribute exists then get 0th dimension of desired
1618 : * field within merged field
1619 : */
1620 0 : if (attrIndex != -1)
1621 : {
1622 0 : SDreadattr(*sdid, attrIndex, (VOIDP) dums);
1623 0 : dims[0] = dums[dum];
1624 :
1625 : /* If this dimension = 1 then field is really 2 dim */
1626 : /* ------------------------------------------------ */
1627 0 : if (dums[dum] == 1)
1628 : {
1629 0 : *rankFld = 2;
1630 : }
1631 : }
1632 : }
1633 :
1634 :
1635 : /* Break out of SDS loop */
1636 : /* --------------------- */
1637 0 : break;
1638 : } /* End of found field section */
1639 : }
1640 : else
1641 : {
1642 : /* First non-active SDS signifies no more, break out of SDS loop */
1643 : /* ------------------------------------------------------------- */
1644 0 : break;
1645 : }
1646 : }
1647 10 : free(utlstr);
1648 10 : return (status);
1649 : }
1650 :
1651 :
1652 :
1653 :
1654 : /*----------------------------------------------------------------------------|
1655 : | BEGIN_PROLOG |
1656 : | |
1657 : | FUNCTION: GDwrrdfield |
1658 : | |
1659 : | DESCRIPTION: Writes/Reads fields |
1660 : | |
1661 : | |
1662 : | Return Value Type Units Description |
1663 : | ============ ====== ========= ===================================== |
1664 : | status intn return status (0) SUCCEED, (-1) FAIL |
1665 : | |
1666 : | INPUTS: |
1667 : | gridID int32 grid structure ID |
1668 : | fieldname char fieldname |
1669 : | code char Write/Read code (w/r) |
1670 : | start int32 start array |
1671 : | stride int32 stride array |
1672 : | edge int32 edge array |
1673 : | datbuf void data buffer for read |
1674 : | |
1675 : | |
1676 : | OUTPUTS: |
1677 : | datbuf void data buffer for write |
1678 : | |
1679 : | |
1680 : | NOTES: |
1681 : | |
1682 : | |
1683 : | Date Programmer Description |
1684 : | ====== ============ ================================================= |
1685 : | Jun 96 Joel Gales Original Programmer |
1686 : | Feb 97 Joel Gales Stride = 1 HDF compression workaround |
1687 : | |
1688 : | END_PROLOG |
1689 : -----------------------------------------------------------------------------*/
1690 : static intn
1691 0 : GDwrrdfield(int32 gridID, const char *fieldname, const char *code,
1692 : int32 start[], int32 stride[], int32 edge[], VOIDP datbuf)
1693 :
1694 : {
1695 : intn i; /* Loop index */
1696 0 : intn status = 0; /* routine return status variable */
1697 :
1698 : int32 fid; /* HDF-EOS file ID */
1699 : int32 sdInterfaceID; /* HDF SDS interface ID */
1700 : int32 sdid; /* SDS ID */
1701 : int32 dum; /* Dummy variable */
1702 : int32 rankSDS; /* Rank of SDS */
1703 : int32 rankFld; /* Rank of field */
1704 :
1705 0 : int32 offset[8] = {0}; /* I/O offset (start) */
1706 : int32 incr[8]; /* I/O increment (stride) */
1707 : int32 count[8]; /* I/O count (edge) */
1708 : int32 dims[8]; /* Field/SDS dimensions */
1709 0 : int32 mrgOffset = 0; /* Merged field offset */
1710 : int32 strideOne; /* Strides = 1 flag */
1711 :
1712 0 : for (i = 0; i < 8; ++i)
1713 0 : incr[i] = 1;
1714 :
1715 : /* Check for valid grid ID */
1716 : /* ----------------------- */
1717 0 : status = GDchkgdid(gridID, "GDwrrdfield", &fid, &sdInterfaceID, &dum);
1718 0 : if (status < 0)
1719 0 : return -1;
1720 :
1721 : /* Check that field exists */
1722 : /* ----------------------- */
1723 0 : status = GDfieldinfo(gridID, fieldname, &rankSDS, dims, &dum, NULL);
1724 :
1725 :
1726 0 : if (status != 0)
1727 : {
1728 0 : HEpush(DFE_GENAPP, "GDwrrdfield", __FILE__, __LINE__);
1729 0 : HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
1730 0 : status = -1;
1731 :
1732 : }
1733 :
1734 :
1735 0 : if (status == 0)
1736 : {
1737 0 : status = GDSDfldsrch(gridID, sdInterfaceID, fieldname, &sdid,
1738 : &rankSDS, &rankFld, &mrgOffset, dims, &dum);
1739 0 : if (status < 0)
1740 0 : return -1;
1741 :
1742 :
1743 : /* Set I/O offset Section */
1744 : /* ---------------------- */
1745 :
1746 : /*
1747 : * If start == NULL (default) set I/O offset of 0th field to
1748 : * offset within merged field (if any) and the rest to 0
1749 : */
1750 0 : if (start == NULL)
1751 : {
1752 0 : for (i = 0; i < rankSDS; i++)
1753 : {
1754 0 : offset[i] = 0;
1755 : }
1756 0 : offset[0] = mrgOffset;
1757 : }
1758 : else
1759 : {
1760 : /*
1761 : * ... otherwise set I/O offset to user values, adjusting the
1762 : * 0th field with the merged field offset (if any)
1763 : */
1764 0 : if (rankFld == rankSDS)
1765 : {
1766 0 : for (i = 0; i < rankSDS; i++)
1767 : {
1768 0 : offset[i] = start[i];
1769 : }
1770 0 : offset[0] += mrgOffset;
1771 : }
1772 : else
1773 : {
1774 : /*
1775 : * If field really 2-dim merged in 3-dim field then set
1776 : * 0th field offset to merge offset and then next two to
1777 : * the user values
1778 : */
1779 0 : for (i = 0; i < rankFld; i++)
1780 : {
1781 0 : offset[i + 1] = start[i];
1782 : }
1783 0 : offset[0] = mrgOffset;
1784 : }
1785 : }
1786 :
1787 :
1788 :
1789 : /* Set I/O stride Section */
1790 : /* ---------------------- */
1791 :
1792 : /*
1793 : * If stride == NULL (default) set I/O stride to 1
1794 : */
1795 0 : if (stride == NULL)
1796 : {
1797 0 : for (i = 0; i < rankSDS; i++)
1798 : {
1799 0 : incr[i] = 1;
1800 : }
1801 : }
1802 : else
1803 : {
1804 : /*
1805 : * ... otherwise set I/O stride to user values
1806 : */
1807 0 : if (rankFld == rankSDS)
1808 : {
1809 0 : for (i = 0; i < rankSDS; i++)
1810 : {
1811 0 : incr[i] = stride[i];
1812 : }
1813 : }
1814 : else
1815 : {
1816 : /*
1817 : * If field really 2-dim merged in 3-dim field then set
1818 : * 0th field stride to 1 and then next two to the user
1819 : * values.
1820 : */
1821 0 : for (i = 0; i < rankFld; i++)
1822 : {
1823 0 : incr[i + 1] = stride[i];
1824 : }
1825 0 : incr[0] = 1;
1826 : }
1827 : }
1828 :
1829 :
1830 :
1831 : /* Set I/O count Section */
1832 : /* --------------------- */
1833 :
1834 : /*
1835 : * If edge == NULL (default) set I/O count to number of remaining
1836 : * entries (dims - start) / increment. Note that 0th field
1837 : * offset corrected for merged field offset (if any).
1838 : */
1839 0 : if (edge == NULL)
1840 : {
1841 0 : for (i = 1; i < rankSDS; i++)
1842 : {
1843 0 : count[i] = (dims[i] - offset[i]) / incr[i];
1844 : }
1845 0 : count[0] = (dims[0] - (offset[0] - mrgOffset)) / incr[0];
1846 : }
1847 : else
1848 : {
1849 : /*
1850 : * ... otherwise set I/O count to user values
1851 : */
1852 0 : if (rankFld == rankSDS)
1853 : {
1854 0 : for (i = 0; i < rankSDS; i++)
1855 : {
1856 0 : count[i] = edge[i];
1857 : }
1858 : }
1859 : else
1860 : {
1861 : /*
1862 : * If field really 2-dim merged in 3-dim field then set
1863 : * 0th field count to 1 and then next two to the user
1864 : * values.
1865 : */
1866 0 : for (i = 0; i < rankFld; i++)
1867 : {
1868 0 : count[i + 1] = edge[i];
1869 : }
1870 0 : count[0] = 1;
1871 : }
1872 : }
1873 :
1874 :
1875 : /* Perform I/O with relevant HDF I/O routine */
1876 : /* ----------------------------------------- */
1877 0 : if (strcmp(code, "w") == 0)
1878 : {
1879 : /* Set strideOne to true (1) */
1880 : /* ------------------------- */
1881 0 : strideOne = 1;
1882 :
1883 :
1884 : /* If incr[i] != 1 set strideOne to false (0) */
1885 : /* ------------------------------------------ */
1886 0 : for (i = 0; i < rankSDS; i++)
1887 : {
1888 0 : if (incr[i] != 1)
1889 : {
1890 0 : strideOne = 0;
1891 0 : break;
1892 : }
1893 : }
1894 :
1895 :
1896 : /*
1897 : * If strideOne is true use NULL parameter for stride. This
1898 : * is a work-around to HDF compression problem
1899 : */
1900 0 : if (strideOne == 1)
1901 : {
1902 0 : status = SDwritedata(sdid, offset, NULL, count,
1903 : (VOIDP) datbuf);
1904 : }
1905 : else
1906 : {
1907 0 : status = SDwritedata(sdid, offset, incr, count,
1908 : (VOIDP) datbuf);
1909 : }
1910 : }
1911 : else
1912 : {
1913 0 : status = SDreaddata(sdid, offset, incr, count,
1914 : (VOIDP) datbuf);
1915 : }
1916 : }
1917 :
1918 0 : return (status);
1919 : }
1920 :
1921 :
1922 : /*----------------------------------------------------------------------------|
1923 : | BEGIN_PROLOG |
1924 : | |
1925 : | FUNCTION: GDreadfield |
1926 : | |
1927 : | DESCRIPTION: Reads data from a grid field. |
1928 : | |
1929 : | |
1930 : | Return Value Type Units Description |
1931 : | ============ ====== ========= ===================================== |
1932 : | status intn return status (0) SUCCEED, (-1) FAIL |
1933 : | |
1934 : | INPUTS: |
1935 : | gridID int32 grid structure ID |
1936 : | fieldname char fieldname |
1937 : | start int32 start array |
1938 : | stride int32 stride array |
1939 : | edge int32 edge array |
1940 : | buffer void data buffer for read |
1941 : | |
1942 : | |
1943 : | OUTPUTS: |
1944 : | None |
1945 : | |
1946 : | NOTES: |
1947 : | |
1948 : | |
1949 : | Date Programmer Description |
1950 : | ====== ============ ================================================= |
1951 : | Jun 96 Joel Gales Original Programmer |
1952 : | |
1953 : | END_PROLOG |
1954 : -----------------------------------------------------------------------------*/
1955 : intn
1956 0 : GDreadfield(int32 gridID, const char *fieldname,
1957 : int32 start[], int32 stride[], int32 edge[], VOIDP buffer)
1958 :
1959 : {
1960 0 : intn status = 0; /* routine return status variable */
1961 :
1962 0 : status = GDwrrdfield(gridID, fieldname, "r", start, stride, edge,
1963 : buffer);
1964 0 : return (status);
1965 : }
1966 :
1967 :
1968 :
1969 :
1970 : /*----------------------------------------------------------------------------|
1971 : | BEGIN_PROLOG |
1972 : | |
1973 : | FUNCTION: GDwrrdattr |
1974 : | |
1975 : | DESCRIPTION: |
1976 : | |
1977 : | |
1978 : | Return Value Type Units Description |
1979 : | ============ ====== ========= ===================================== |
1980 : | status intn return status (0) SUCCEED, (-1) FAIL |
1981 : | |
1982 : | INPUTS: |
1983 : | gridID int32 grid structure ID |
1984 : | attrname char attribute name |
1985 : | numbertype int32 attribute HDF numbertype |
1986 : | count int32 Number of attribute elements |
1987 : | wrcode char Read/Write Code "w/r" |
1988 : | datbuf void I/O buffer |
1989 : | |
1990 : | OUTPUTS: |
1991 : | datbuf |
1992 : | |
1993 : | NOTES: |
1994 : | |
1995 : | |
1996 : | Date Programmer Description |
1997 : | ====== ============ ================================================= |
1998 : | Jun 96 Joel Gales Original Programmer |
1999 : | Oct 96 Joel Gales Get Attribute Vgroup ID from external array |
2000 : | |
2001 : | END_PROLOG |
2002 : -----------------------------------------------------------------------------*/
2003 : static intn
2004 1 : GDwrrdattr(int32 gridID, const char *attrname, int32 numbertype, int32 count,
2005 : const char *wrcode, VOIDP datbuf)
2006 :
2007 : {
2008 : intn status; /* routine return status variable */
2009 :
2010 : int32 fid; /* HDF-EOS file ID */
2011 : int32 attrVgrpID; /* Grid attribute ID */
2012 : int32 dum; /* dummy variable */
2013 1 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
2014 :
2015 :
2016 : /* Check Grid id */
2017 1 : status = GDchkgdid(gridID, "GDwrrdattr", &fid, &dum, &dum);
2018 :
2019 1 : if (status == 0)
2020 : {
2021 : /* Perform Attribute I/O */
2022 : /* --------------------- */
2023 1 : int gID = gridID % idOffset;
2024 1 : if (gID >= NGRID)
2025 : {
2026 0 : return -1;
2027 : }
2028 1 : attrVgrpID = GDXGrid[gID].VIDTable[1];
2029 1 : status = EHattr(fid, attrVgrpID, attrname, numbertype, count,
2030 : wrcode, datbuf);
2031 : }
2032 1 : return (status);
2033 : }
2034 :
2035 : /*----------------------------------------------------------------------------|
2036 : | BEGIN_PROLOG |
2037 : | |
2038 : | FUNCTION: GDreadattr |
2039 : | |
2040 : | DESCRIPTION: Reads attribute from a grid. |
2041 : | |
2042 : | |
2043 : | Return Value Type Units Description |
2044 : | ============ ====== ========= ===================================== |
2045 : | status intn return status (0) SUCCEED, (-1) FAIL |
2046 : | |
2047 : | INPUTS: |
2048 : | gridID int32 grid structure ID |
2049 : | attrname char attribute name |
2050 : | |
2051 : | OUTPUTS: |
2052 : | datbuf void I/O buffer |
2053 : | |
2054 : | NOTES: |
2055 : | |
2056 : | |
2057 : | Date Programmer Description |
2058 : | ====== ============ ================================================= |
2059 : | Jun 96 Joel Gales Original Programmer |
2060 : | |
2061 : | END_PROLOG |
2062 : -----------------------------------------------------------------------------*/
2063 : intn
2064 1 : GDreadattr(int32 gridID, const char *attrname, VOIDP datbuf)
2065 : {
2066 1 : intn status = 0; /* routine return status variable */
2067 1 : int32 dum = 0; /* dummy variable */
2068 :
2069 : /* Call GDwrrdattr routine to read attribute */
2070 : /* ----------------------------------------- */
2071 1 : status = GDwrrdattr(gridID, attrname, dum, dum, "r", datbuf);
2072 :
2073 1 : return (status);
2074 : }
2075 :
2076 :
2077 :
2078 :
2079 :
2080 : /*----------------------------------------------------------------------------|
2081 : | BEGIN_PROLOG |
2082 : | |
2083 : | FUNCTION: GDattrinfo |
2084 : | |
2085 : | DESCRIPTION: |
2086 : | |
2087 : | |
2088 : | Return Value Type Units Description |
2089 : | ============ ====== ========= ===================================== |
2090 : | status intn return status (0) SUCCEED, (-1) FAIL |
2091 : | |
2092 : | INPUTS: |
2093 : | gridID int32 grid structure ID |
2094 : | attrname char attribute name |
2095 : | |
2096 : | OUTPUTS: |
2097 : | numbertype int32 attribute HDF numbertype |
2098 : | count int32 Number of attribute elements |
2099 : | |
2100 : | |
2101 : | OUTPUTS: |
2102 : | None |
2103 : | |
2104 : | NOTES: |
2105 : | |
2106 : | |
2107 : | Date Programmer Description |
2108 : | ====== ============ ================================================= |
2109 : | Jun 96 Joel Gales Original Programmer |
2110 : | Oct 96 Joel Gales Get Attribute Vgroup ID from external array |
2111 : | |
2112 : | END_PROLOG |
2113 : -----------------------------------------------------------------------------*/
2114 : intn
2115 0 : GDattrinfo(int32 gridID, const char *attrname, int32 * numbertype, int32 * count)
2116 : {
2117 0 : intn status = 0; /* routine return status variable */
2118 :
2119 0 : int32 fid = 0; /* HDF-EOS file ID */
2120 : int32 attrVgrpID; /* Grid attribute ID */
2121 : int32 dum; /* dummy variable */
2122 0 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
2123 :
2124 0 : status = GDchkgdid(gridID, "GDattrinfo", &fid, &dum, &dum);
2125 0 : if (status < 0)
2126 0 : return -1;
2127 :
2128 0 : int gID = gridID % idOffset;
2129 0 : if (gID >= NGRID)
2130 : {
2131 0 : return -1;
2132 : }
2133 0 : attrVgrpID = GDXGrid[gID].VIDTable[1];
2134 :
2135 0 : status = EHattrinfo(fid, attrVgrpID, attrname, numbertype,
2136 : count);
2137 :
2138 0 : return (status);
2139 : }
2140 :
2141 :
2142 :
2143 :
2144 :
2145 :
2146 : /*----------------------------------------------------------------------------|
2147 : | BEGIN_PROLOG |
2148 : | |
2149 : | FUNCTION: GDinqattrs |
2150 : | |
2151 : | DESCRIPTION: |
2152 : | |
2153 : | |
2154 : | Return Value Type Units Description |
2155 : | ============ ====== ========= ===================================== |
2156 : | nattr int32 Number of attributes in swath struct |
2157 : | |
2158 : | INPUTS: |
2159 : | grid ID int32 grid structure ID |
2160 : | |
2161 : | OUTPUTS: |
2162 : | attrnames char Attribute names in swath struct |
2163 : | (Comma-separated list) |
2164 : | strbufsize int32 Attributes name list string length |
2165 : | |
2166 : | OUTPUTS: |
2167 : | None |
2168 : | |
2169 : | NOTES: |
2170 : | |
2171 : | |
2172 : | Date Programmer Description |
2173 : | ====== ============ ================================================= |
2174 : | Jun 96 Joel Gales Original Programmer |
2175 : | Oct 96 Joel Gales Initialize nattr |
2176 : | Oct 96 Joel Gales Get Attribute Vgroup ID from external array |
2177 : | |
2178 : | END_PROLOG |
2179 : -----------------------------------------------------------------------------*/
2180 : int32
2181 4 : GDinqattrs(int32 gridID, char *attrnames, int32 * strbufsize)
2182 : {
2183 : intn status; /* routine return status variable */
2184 :
2185 : int32 fid; /* HDF-EOS file ID */
2186 : int32 attrVgrpID; /* Grid attribute ID */
2187 : int32 dum; /* dummy variable */
2188 4 : int32 nattr = 0; /* Number of attributes */
2189 4 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
2190 :
2191 :
2192 : /* Check Grid id */
2193 4 : status = GDchkgdid(gridID, "GDinqattrs", &fid, &dum, &dum);
2194 :
2195 4 : if (status == 0)
2196 : {
2197 4 : int gID = gridID % idOffset;
2198 4 : if (gID >= NGRID)
2199 : {
2200 0 : return -1;
2201 : }
2202 4 : attrVgrpID = GDXGrid[gID].VIDTable[1];
2203 4 : nattr = EHattrcat(fid, attrVgrpID, attrnames, strbufsize);
2204 : }
2205 :
2206 4 : return (nattr);
2207 : }
2208 :
2209 :
2210 :
2211 :
2212 :
2213 :
2214 : #define REMQUOTE(x) do { \
2215 : char* l_x = x; \
2216 : const size_t l_x_len = strlen(l_x); \
2217 : if (l_x_len >= 2 && l_x[0] == '"' && l_x[l_x_len - 1] == '"') {\
2218 : memmove(l_x, l_x + 1, l_x_len - 2); \
2219 : l_x[l_x_len - 2] = 0; \
2220 : } \
2221 : } while(0)
2222 :
2223 :
2224 : /*----------------------------------------------------------------------------|
2225 : | BEGIN_PROLOG |
2226 : | |
2227 : | FUNCTION: GDinqfields |
2228 : | |
2229 : | DESCRIPTION: Retrieve information about all data fields defined in a grid. |
2230 : | |
2231 : | |
2232 : | Return Value Type Units Description |
2233 : | ============ ====== ========= ===================================== |
2234 : | nFld int32 Number of fields in swath |
2235 : | |
2236 : | INPUTS: |
2237 : | gridID int32 grid structure ID |
2238 : | |
2239 : | |
2240 : | OUTPUTS: |
2241 : | fieldlist char Field names (comma-separated) |
2242 : | rank int32 Array of ranks |
2243 : | numbertype int32 Array of HDF number types |
2244 : | |
2245 : | NOTES: |
2246 : | |
2247 : | |
2248 : | Date Programmer Description |
2249 : | ====== ============ ================================================= |
2250 : | Jun 96 Joel Gales Original Programmer |
2251 : | Aug 96 Joel Gales Make metadata ODL compliant |
2252 : | Feb 97 Joel Gales Set nFld to -1 if status = -1 |
2253 : | |
2254 : | END_PROLOG |
2255 : -----------------------------------------------------------------------------*/
2256 : int32
2257 6 : GDinqfields(int32 gridID, char *fieldlist, int32 rank[],
2258 : int32 numbertype[])
2259 : {
2260 : intn status; /* routine return status variable */
2261 :
2262 : int32 fid; /* HDF-EOS file ID */
2263 : int32 sdInterfaceID; /* HDF SDS interface ID */
2264 : int32 gdVgrpID; /* Grid root Vgroup ID */
2265 6 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
2266 6 : int32 nFld = 0; /* Number of mappings */
2267 : int32 slen[8]; /* String length array */
2268 :
2269 : char *metabuf; /* Pointer to structural metadata (SM) */
2270 : char *metaptrs[2];/* Pointers to begin and end of SM section */
2271 : char gridname[80]; /* Grid Name */
2272 : char *utlstr;/* Utility string */
2273 : char *ptr[8]; /* String pointer array */
2274 :
2275 : /* Allocate space for utility string */
2276 : /* --------------------------------- */
2277 6 : utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
2278 6 : if(utlstr == NULL)
2279 : {
2280 0 : HEpush(DFE_NOSPACE,"GDinqfields", __FILE__, __LINE__);
2281 0 : return(-1);
2282 : }
2283 : /* Check for valid grid id */
2284 : /* ----------------------- */
2285 6 : status = GDchkgdid(gridID, "GDinqfields", &fid, &sdInterfaceID, &gdVgrpID);
2286 6 : if (status == 0)
2287 : {
2288 :
2289 : /* If field names, ranks, or number types desired ... */
2290 : /* --------------------------------------------------- */
2291 6 : if (fieldlist != NULL || rank != NULL || numbertype != NULL)
2292 : {
2293 : /* Get grid name */
2294 : /* ------------- */
2295 6 : int gID = gridID % idOffset;
2296 6 : if (gID >= NGRID)
2297 : {
2298 0 : free(utlstr);
2299 0 : return -1;
2300 : }
2301 6 : VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
2302 :
2303 :
2304 : /* Get pointers to "DataField" section within SM */
2305 : /* --------------------------------------------- */
2306 6 : metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
2307 : "DataField", metaptrs);
2308 6 : if(metabuf == NULL)
2309 : {
2310 0 : free(utlstr);
2311 0 : return(-1);
2312 : }
2313 :
2314 :
2315 : /* If field names are desired then "clear" name buffer */
2316 : /* --------------------------------------------------- */
2317 6 : if (fieldlist != NULL)
2318 : {
2319 6 : fieldlist[0] = 0;
2320 : }
2321 :
2322 :
2323 : /* Begin loop through mapping entries in metadata */
2324 : /* ---------------------------------------------- */
2325 : while (1)
2326 : {
2327 : /* Search for OBJECT string */
2328 : /* ------------------------ */
2329 110 : metaptrs[0] = strstr(metaptrs[0], "\t\tOBJECT=");
2330 :
2331 :
2332 : /* If found within "Data" Field metadata section .. */
2333 : /* ------------------------------------------------ */
2334 110 : if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
2335 : {
2336 : /* Get Fieldnames (if desired) */
2337 : /* --------------------------- */
2338 104 : if (fieldlist != NULL)
2339 : {
2340 : /* Check 1st for old meta data then new */
2341 : /* ------------------------------------ */
2342 104 : EHgetmetavalue(metaptrs, "OBJECT", utlstr);
2343 :
2344 : /*
2345 : * If OBJECT value begins with double quote then old
2346 : * metadata, field name is OBJECT value. Otherwise
2347 : * search for "DataFieldName" string
2348 : */
2349 :
2350 104 : if (utlstr[0] != '"')
2351 : {
2352 104 : strcpy(utlstr, "\t\t\t\t");
2353 104 : strcat(utlstr, "DataFieldName");
2354 104 : strcat(utlstr, "=");
2355 104 : metaptrs[0] = strstr(metaptrs[0], utlstr);
2356 104 : EHgetmetavalue(metaptrs, "DataFieldName", utlstr);
2357 : }
2358 :
2359 : /* Strip off double quotes */
2360 : /* ----------------------- */
2361 104 : REMQUOTE(utlstr);
2362 :
2363 :
2364 : /* Add to fieldlist */
2365 : /* ---------------- */
2366 104 : if (nFld > 0)
2367 : {
2368 98 : strcat(fieldlist, ",");
2369 : }
2370 104 : strcat(fieldlist, utlstr);
2371 :
2372 : }
2373 : /* Get Numbertype */
2374 104 : if (numbertype != NULL)
2375 : {
2376 104 : EHgetmetavalue(metaptrs, "DataType", utlstr);
2377 104 : numbertype[nFld] = EHnumstr(utlstr);
2378 : }
2379 : /*
2380 : * Get Rank (if desired) by counting # of dimensions in
2381 : * "DimList" string
2382 : */
2383 104 : if (rank != NULL)
2384 : {
2385 104 : EHgetmetavalue(metaptrs, "DimList", utlstr);
2386 104 : rank[nFld] = EHparsestr(utlstr, ',', ptr, CPL_ARRAYSIZE(ptr), slen, CPL_ARRAYSIZE(slen));
2387 104 : if (rank[nFld] < 0)
2388 : {
2389 0 : status = -1;
2390 0 : break;
2391 : }
2392 : }
2393 : /* Increment number of fields */
2394 104 : nFld++;
2395 : }
2396 : else
2397 : /* No more fields found */
2398 : {
2399 : break;
2400 : }
2401 : }
2402 6 : free(metabuf);
2403 : }
2404 : }
2405 :
2406 : /* Set nFld to -1 if error status exists */
2407 : /* ------------------------------------- */
2408 6 : if (status == -1)
2409 : {
2410 0 : nFld = -1;
2411 : }
2412 6 : free(utlstr);
2413 6 : return (nFld);
2414 : }
2415 :
2416 :
2417 :
2418 :
2419 :
2420 : /*----------------------------------------------------------------------------|
2421 : | BEGIN_PROLOG |
2422 : | |
2423 : | FUNCTION: GDnentries |
2424 : | |
2425 : | DESCRIPTION: Returns number of entries and descriptive string buffer |
2426 : | size for a specified entity. |
2427 : | |
2428 : | |
2429 : | Return Value Type Units Description |
2430 : | ============ ====== ========= ===================================== |
2431 : | nEntries int32 Number of entries |
2432 : | |
2433 : | INPUTS: |
2434 : | gridID int32 grid structure ID |
2435 : | entrycode int32 Entry code |
2436 : | HDFE_NENTDIM (0) |
2437 : | HDFE_NENTDFLD (4) |
2438 : | |
2439 : | |
2440 : | OUTPUTS: |
2441 : | strbufsize int32 Length of comma-separated list |
2442 : | (Does not include null-terminator |
2443 : | |
2444 : | NOTES: |
2445 : | |
2446 : | |
2447 : | Date Programmer Description |
2448 : | ====== ============ ================================================= |
2449 : | Jun 96 Joel Gales Original Programmer |
2450 : | Aug 96 Joel Gales Make metadata ODL compliant |
2451 : | Feb 97 Joel Gales Set nEntries to -1 if status = -1 |
2452 : | |
2453 : | END_PROLOG |
2454 : -----------------------------------------------------------------------------*/
2455 : int32
2456 6 : GDnentries(int32 gridID, int32 entrycode, int32 * strbufsize)
2457 :
2458 : {
2459 : intn status; /* routine return status variable */
2460 : intn i; /* Loop index */
2461 :
2462 : int32 fid; /* HDF-EOS file ID */
2463 : int32 sdInterfaceID; /* HDF SDS interface ID */
2464 : int32 gdVgrpID; /* Grid root Vgroup ID */
2465 6 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
2466 6 : int32 nEntries = 0; /* Number of entries */
2467 : int32 metaflag; /* Old (0), New (1) metadata flag) */
2468 6 : int32 nVal = 0; /* Number of strings to search for */
2469 :
2470 6 : char *metabuf = NULL; /* Pointer to structural metadata (SM) */
2471 6 : char *metaptrs[2] = {NULL, NULL};/* Pointers to begin and end of SM section */
2472 : char gridname[80]; /* Grid Name */
2473 : char *utlstr;/* Utility string */
2474 : char valName[2][32]; /* Strings to search for */
2475 :
2476 6 : memset(valName, 0, sizeof(valName));
2477 :
2478 : /* Allocate space for utility string */
2479 : /* --------------------------------- */
2480 6 : utlstr = (char *) calloc(UTLSTR_MAX_SIZE, sizeof(char));
2481 6 : if(utlstr == NULL)
2482 : {
2483 0 : HEpush(DFE_NOSPACE,"GDnentries", __FILE__, __LINE__);
2484 0 : return(-1);
2485 : }
2486 6 : status = GDchkgdid(gridID, "GDnentries", &fid, &sdInterfaceID, &gdVgrpID);
2487 :
2488 6 : if (status == 0)
2489 : {
2490 : /* Get grid name */
2491 6 : int gID = gridID % idOffset;
2492 6 : if (gID >= NGRID)
2493 : {
2494 0 : free(utlstr);
2495 0 : return -1;
2496 : }
2497 :
2498 6 : VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
2499 :
2500 : /* Zero out string buffer size */
2501 6 : *strbufsize = 0;
2502 :
2503 :
2504 : /*
2505 : * Get pointer to relevant section within SM and Get names of
2506 : * metadata strings to inquire about
2507 : */
2508 6 : switch (entrycode)
2509 : {
2510 0 : case HDFE_NENTDIM:
2511 : {
2512 0 : metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
2513 : "Dimension", metaptrs);
2514 0 : if(metabuf == NULL)
2515 : {
2516 0 : free(utlstr);
2517 0 : return(-1);
2518 : }
2519 :
2520 0 : nVal = 1;
2521 0 : strcpy(&valName[0][0], "DimensionName");
2522 : }
2523 0 : break;
2524 :
2525 6 : case HDFE_NENTDFLD:
2526 : {
2527 6 : metabuf = (char *) EHmetagroup(sdInterfaceID, gridname, "g",
2528 : "DataField", metaptrs);
2529 6 : if(metabuf == NULL)
2530 : {
2531 0 : free(utlstr);
2532 0 : return(-1);
2533 : }
2534 :
2535 6 : nVal = 1;
2536 6 : strcpy(&valName[0][0], "DataFieldName");
2537 : }
2538 6 : break;
2539 : }
2540 :
2541 6 : if (!metabuf || metaptrs[0] == NULL)
2542 : {
2543 0 : free(metabuf);
2544 0 : free(utlstr);
2545 0 : return -1;
2546 : }
2547 :
2548 : /*
2549 : * Check for presence of 'GROUP="' string If found then old metadata,
2550 : * search on OBJECT string
2551 : */
2552 6 : metaflag = (strstr(metabuf, "GROUP=\"") == NULL) ? 1 : 0;
2553 6 : if (metaflag == 0)
2554 : {
2555 0 : nVal = 1;
2556 0 : strcpy(&valName[0][0], "\t\tOBJECT");
2557 : }
2558 :
2559 :
2560 : /* Begin loop through entries in metadata */
2561 : /* -------------------------------------- */
2562 : while (1)
2563 : {
2564 : /* Search for first string */
2565 110 : strcpy(utlstr, &valName[0][0]);
2566 110 : strcat(utlstr, "=");
2567 110 : metaptrs[0] = strstr(metaptrs[0], utlstr);
2568 :
2569 : /* If found within relevant metadata section ... */
2570 110 : if (metaptrs[0] < metaptrs[1] && metaptrs[0] != NULL)
2571 : {
2572 208 : for (i = 0; i < nVal; i++)
2573 : {
2574 : /*
2575 : * Get all string values Don't count quotes
2576 : */
2577 104 : EHgetmetavalue(metaptrs, &valName[i][0], utlstr);
2578 104 : if( utlstr[0] == '"' && utlstr[strlen(utlstr)-1] == '"' )
2579 4 : *strbufsize += (int32)strlen(utlstr) - 2;
2580 : else
2581 100 : *strbufsize += (int32)strlen(utlstr);
2582 : }
2583 : /* Increment number of entries */
2584 104 : nEntries++;
2585 :
2586 : /* Go to end of OBJECT */
2587 104 : metaptrs[0] = strstr(metaptrs[0], "END_OBJECT");
2588 : }
2589 : else
2590 : /* No more entries found */
2591 : {
2592 : break;
2593 : }
2594 : }
2595 6 : free(metabuf);
2596 :
2597 :
2598 : /* Count comma separators & slashes (if mappings) */
2599 : /* ---------------------------------------------- */
2600 6 : if (nEntries > 0)
2601 : {
2602 6 : *strbufsize += nEntries - 1;
2603 6 : *strbufsize += (nVal - 1) * nEntries;
2604 : }
2605 : }
2606 :
2607 :
2608 : /* Set nEntries to -1 if error status exists */
2609 : /* ----------------------------------------- */
2610 6 : if (status == -1)
2611 : {
2612 0 : nEntries = -1;
2613 : }
2614 :
2615 6 : free(utlstr);
2616 6 : return (nEntries);
2617 : }
2618 :
2619 :
2620 :
2621 :
2622 :
2623 : /*----------------------------------------------------------------------------|
2624 : | BEGIN_PROLOG |
2625 : | |
2626 : | FUNCTION: GDinqgrid |
2627 : | |
2628 : | DESCRIPTION: Returns number and names of grid structures in file |
2629 : | |
2630 : | |
2631 : | Return Value Type Units Description |
2632 : | ============ ====== ========= ===================================== |
2633 : | nGrid int32 Number of grid structures in file |
2634 : | |
2635 : | INPUTS: |
2636 : | filename char HDF-EOS filename |
2637 : | |
2638 : | OUTPUTS: |
2639 : | gridlist char List of grid names (comma-separated) |
2640 : | strbufsize int32 Length of gridlist |
2641 : | |
2642 : | NOTES: |
2643 : | |
2644 : | |
2645 : | Date Programmer Description |
2646 : | ====== ============ ================================================= |
2647 : | Jun 96 Joel Gales Original Programmer |
2648 : | |
2649 : | END_PROLOG |
2650 : -----------------------------------------------------------------------------*/
2651 : int32
2652 25 : GDinqgrid(const char *filename, char *gridlist, int32 * strbufsize)
2653 : {
2654 : int32 nGrid; /* Number of grid structures in file */
2655 :
2656 : /* Call "EHinquire" routine */
2657 : /* ------------------------ */
2658 25 : nGrid = EHinquire(filename, "GRID", gridlist, strbufsize);
2659 :
2660 25 : return (nGrid);
2661 : }
2662 :
2663 :
2664 :
2665 : /*----------------------------------------------------------------------------|
2666 : | BEGIN_PROLOG |
2667 : | |
2668 : | FUNCTION: GDgetfillvalue |
2669 : | |
2670 : | DESCRIPTION: Retrieves fill value for a specified field. |
2671 : | |
2672 : | |
2673 : | Return Value Type Units Description |
2674 : | ============ ====== ========= ===================================== |
2675 : | status intn return status (0) SUCCEED, (-1) FAIL |
2676 : | |
2677 : | INPUTS: |
2678 : | gridID int32 grid structure ID |
2679 : | fieldname char field name |
2680 : | |
2681 : | OUTPUTS: |
2682 : | fillval void fill value |
2683 : | |
2684 : | NOTES: |
2685 : | |
2686 : | |
2687 : | Date Programmer Description |
2688 : | ====== ============ ================================================= |
2689 : | Jun 96 Joel Gales Original Programmer |
2690 : | |
2691 : | END_PROLOG |
2692 : -----------------------------------------------------------------------------*/
2693 : intn
2694 2 : GDgetfillvalue(int32 gridID, const char *fieldname, VOIDP fillval)
2695 : {
2696 : intn status; /* routine return status variable */
2697 :
2698 : int32 nt; /* Number type */
2699 : int32 dims[8]; /* Dimensions array */
2700 : int32 dum; /* Dummy variable */
2701 :
2702 : char name[80]; /* Fill value "attribute" name */
2703 :
2704 2 : status = GDchkgdid(gridID, "GDgetfillvalue", &dum, &dum, &dum);
2705 :
2706 : /* Check for valid grid ID */
2707 2 : if (status == 0)
2708 : {
2709 : /* Get field info */
2710 1 : status = GDfieldinfo(gridID, fieldname, &dum, dims, &nt, NULL);
2711 :
2712 1 : if (status == 0)
2713 : {
2714 : /* Read fill value attribute */
2715 1 : strcpy(name, "_FV_");
2716 1 : strcat(name, fieldname);
2717 1 : status = GDreadattr(gridID, name, fillval);
2718 : }
2719 : else
2720 : {
2721 0 : HEpush(DFE_GENAPP, "GDgetfillvalue", __FILE__, __LINE__);
2722 0 : HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
2723 : }
2724 :
2725 : }
2726 2 : return (status);
2727 : }
2728 :
2729 :
2730 :
2731 :
2732 :
2733 : /*----------------------------------------------------------------------------|
2734 : | BEGIN_PROLOG |
2735 : | |
2736 : | FUNCTION: GDdetach |
2737 : | |
2738 : | DESCRIPTION: Detaches from grid interface and performs file housekeeping. |
2739 : | |
2740 : | |
2741 : | Return Value Type Units Description |
2742 : | ============ ====== ========= ===================================== |
2743 : | status intn return status (0) SUCCEED, (-1) FAIL |
2744 : | |
2745 : | INPUTS: |
2746 : | gridID int32 grid structure ID |
2747 : | |
2748 : | |
2749 : | OUTPUTS: |
2750 : | None |
2751 : | |
2752 : | NOTES: |
2753 : | |
2754 : | |
2755 : | Date Programmer Description |
2756 : | ====== ============ ================================================= |
2757 : | Jun 96 Joel Gales Original Programmer |
2758 : | Sep 96 Joel Gales Setup dim names for SDsetdimname in dimbuf1 rather |
2759 : | that utlstr |
2760 : | Oct 96 Joel Gales Detach Grid Vgroups |
2761 : | Oct 96 Joel Gales "Detach" from SDS |
2762 : | Nov 96 Joel Gales Call GDchkgdid to check for proper grid ID |
2763 : | Dec 96 Joel Gales Add multiple vertical subsetting garbage collection |
2764 : | Oct 98 Abe Taaheri Added GDXRegion[k]->DimNamePtr[i] =0; after freeing |
2765 : | memory |
2766 : | Sep 99 Abe Taaheri Changed memcpy to memmove because of overlapping |
2767 : | source and destination for GDXSDcomb, nameptr, and |
2768 : | dimptr. memcpy may cause unexpected results. |
2769 : | |
2770 : | END_PROLOG |
2771 : -----------------------------------------------------------------------------*/
2772 : intn
2773 13 : GDdetach(int32 gridID)
2774 :
2775 : {
2776 : intn i; /* Loop index */
2777 : intn k; /* Loop index */
2778 13 : intn status = 0; /* routine return status variable */
2779 :
2780 : int32 sdInterfaceID; /* SDS interface ID */
2781 : int32 gID; /* Grid ID - offset */
2782 13 : int32 idOffset = GDIDOFFSET; /* Grid ID offset */
2783 : int32 dum; /* Dummy variable */
2784 :
2785 : char gridname[VGNAMELENMAX + 1]; /* Grid name */
2786 :
2787 :
2788 13 : status = GDchkgdid(gridID, "GDdetach", &dum, &sdInterfaceID, &dum);
2789 :
2790 13 : if (status == 0)
2791 : {
2792 13 : gID = gridID % idOffset;
2793 13 : if (gID >= NGRID)
2794 : {
2795 0 : return -1;
2796 : }
2797 13 : VgetnameSafe(GDXGrid[gID].IDTable, gridname, sizeof(gridname));
2798 :
2799 :
2800 : /* "Detach" from previously attached SDSs */
2801 : /* -------------------------------------- */
2802 18 : for (k = 0; k < GDXGrid[gID].nSDS; k++)
2803 : {
2804 5 : SDendaccess(GDXGrid[gID].sdsID[k]);
2805 : }
2806 13 : free(GDXGrid[gID].sdsID);
2807 13 : GDXGrid[gID].sdsID = 0;
2808 13 : GDXGrid[gID].nSDS = 0;
2809 :
2810 :
2811 :
2812 : /* Detach Grid Vgroups */
2813 : /* ------------------- */
2814 13 : Vdetach(GDXGrid[gID].VIDTable[0]);
2815 13 : Vdetach(GDXGrid[gID].VIDTable[1]);
2816 13 : Vdetach(GDXGrid[gID].IDTable);
2817 :
2818 13 : GDXGrid[gID].active = 0;
2819 13 : GDXGrid[gID].VIDTable[0] = 0;
2820 13 : GDXGrid[gID].VIDTable[1] = 0;
2821 13 : GDXGrid[gID].IDTable = 0;
2822 13 : GDXGrid[gID].fid = 0;
2823 :
2824 :
2825 :
2826 :
2827 : /* Free Region Pointers */
2828 : /* -------------------- */
2829 3341 : for (k = 0; k < NGRIDREGN; k++)
2830 : {
2831 3328 : if (GDXRegion[k] != 0 &&
2832 0 : GDXRegion[k]->gridID == gridID)
2833 : {
2834 0 : for (i = 0; i < 8; i++)
2835 : {
2836 0 : if (GDXRegion[k]->DimNamePtr[i] != 0)
2837 : {
2838 0 : free(GDXRegion[k]->DimNamePtr[i]);
2839 0 : GDXRegion[k]->DimNamePtr[i] = 0;
2840 : }
2841 : }
2842 :
2843 0 : free(GDXRegion[k]);
2844 0 : GDXRegion[k] = 0;
2845 : }
2846 : }
2847 : }
2848 13 : return (status);
2849 : }
2850 :
2851 :
2852 : /*----------------------------------------------------------------------------|
2853 : | BEGIN_PROLOG |
2854 : | |
2855 : | FUNCTION: GDclose |
2856 : | |
2857 : | DESCRIPTION: Closes file. |
2858 : | |
2859 : | |
2860 : | Return Value Type Units Description |
2861 : | ============ ====== ========= ===================================== |
2862 : | status intn return status (0) SUCCEED, (-1) FAIL |
2863 : | |
2864 : | INPUTS: |
2865 : | fid int32 File ID |
2866 : | |
2867 : | |
2868 : | OUTPUTS: |
2869 : | None |
2870 : | |
2871 : | NOTES: |
2872 : | |
2873 : | |
2874 : | Date Programmer Description |
2875 : | ====== ============ ================================================= |
2876 : | Jun 96 Joel Gales Original Programmer |
2877 : | |
2878 : | END_PROLOG |
2879 : -----------------------------------------------------------------------------*/
2880 : intn
2881 26 : GDclose(int32 fid)
2882 :
2883 : {
2884 26 : intn status = 0; /* routine return status variable */
2885 :
2886 : /* Call EHclose to perform file close */
2887 : /* ---------------------------------- */
2888 26 : status = EHclose(fid);
2889 :
2890 26 : return (status);
2891 : }
2892 :
2893 : /***********************************************
2894 : GDwrrdtile --
2895 : This function is the underlying function below GDwritetile and
2896 : GDreadtile.
2897 :
2898 :
2899 : Author--
2900 : Alexis Zubrow
2901 :
2902 : ********************************************************/
2903 :
2904 : static intn
2905 0 : GDwrrdtile(int32 gridID, const char *fieldname, const char *code, int32 start[],
2906 : VOIDP datbuf)
2907 : {
2908 : intn i; /* Loop index */
2909 0 : intn status = 0; /* routine return status variable */
2910 :
2911 : int32 fid; /* HDF-EOS file ID */
2912 : int32 sdInterfaceID; /* HDF SDS interface ID */
2913 : int32 sdid; /* SDS ID */
2914 :
2915 : int32 dum; /* Dummy variable */
2916 : int32 rankSDS; /* Rank of SDS/Field */
2917 :
2918 : int32 dims[8]; /* Field/SDS dimensions */
2919 : int32 tileFlags; /* flag to determine if field is tiled */
2920 : int32 numTileDims;/* number of tiles spanning a dimension */
2921 : HDF_CHUNK_DEF tileDef; /* union holding tiling info. */
2922 :
2923 :
2924 : /* Get gridID */
2925 0 : status = GDchkgdid(gridID, "GDwrrdtile", &fid, &sdInterfaceID, &dum);
2926 0 : if (status == 0)
2927 : {
2928 :
2929 : /* Get field info */
2930 0 : status = GDfieldinfo(gridID, fieldname, &rankSDS, dims, &dum, NULL);
2931 :
2932 0 : if (status == 0)
2933 : {
2934 :
2935 : /* Check whether fieldname is in SDS (multi-dim field) */
2936 : /* --------------------------------------------------- */
2937 0 : status = GDSDfldsrch(gridID, sdInterfaceID, fieldname, &sdid,
2938 : &rankSDS, &dum, &dum, dims, &dum);
2939 0 : if (status < 0)
2940 0 : return -1;
2941 :
2942 :
2943 : /*
2944 : * Check for errors in parameters passed to GDwritetile or
2945 : * GDreadtile
2946 : */
2947 :
2948 : /* Check if untiled field */
2949 0 : status = SDgetchunkinfo(sdid, &tileDef, &tileFlags);
2950 0 : if (tileFlags == HDF_NONE)
2951 : {
2952 0 : HEpush(DFE_GENAPP, "GDwrrdtile", __FILE__, __LINE__);
2953 0 : HEreport("Field \"%s\" is not tiled.\n", fieldname);
2954 0 : status = -1;
2955 0 : return (status);
2956 :
2957 : }
2958 :
2959 : /*
2960 : * Check if rd/wr tilecoords are within the extent of the field
2961 : */
2962 0 : for (i = 0; i < rankSDS; i++)
2963 : {
2964 : /*
2965 : * Calculate the number of tiles which span a dimension of
2966 : * the field
2967 : */
2968 0 : numTileDims = dims[i] / tileDef.chunk_lengths[i];
2969 0 : if ((start[i] >= numTileDims) || (start[i] < 0))
2970 : {
2971 : /*
2972 : * ERROR INDICATING BEYOND EXTENT OF THAT DIMENSION OR
2973 : * NEGATIVE TILECOORDS
2974 : */
2975 0 : HEpush(DFE_GENAPP, "GDwrrdtile", __FILE__, __LINE__);
2976 0 : HEreport("Tilecoords for dimension \"%d\" ...\n", i);
2977 0 : HEreport("is beyond the extent of dimension length\n");
2978 0 : status = -1;
2979 :
2980 : }
2981 : }
2982 :
2983 0 : if (status == -1)
2984 : {
2985 0 : return (status);
2986 : }
2987 :
2988 :
2989 : /* Actually write/read to the field */
2990 :
2991 0 : if (strcmp(code, "w") == 0) /* write tile */
2992 : {
2993 0 : status = SDwritechunk(sdid, start, (VOIDP) datbuf);
2994 : }
2995 0 : else if (strcmp(code, "r") == 0) /* read tile */
2996 : {
2997 0 : status = SDreadchunk(sdid, start, (VOIDP) datbuf);
2998 : }
2999 :
3000 :
3001 : }
3002 :
3003 : /* Non-existent fieldname */
3004 : else
3005 : {
3006 0 : HEpush(DFE_GENAPP, "GDwrrdtile", __FILE__, __LINE__);
3007 0 : HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
3008 0 : status = -1;
3009 : }
3010 :
3011 : }
3012 :
3013 0 : return (status);
3014 : }
3015 :
3016 : /***********************************************
3017 : GDtileinfo --
3018 : This function queries the field to determine if it is tiled. If it is
3019 : tile, one can retrieve some of the characteristics of the tiles.
3020 :
3021 : Author-- Alexis Zubrow
3022 :
3023 : ********************************************************/
3024 :
3025 :
3026 : intn
3027 1 : GDtileinfo(int32 gridID, const char *fieldname, int32 * tilecode, int32 * tilerank,
3028 : int32 tiledims[])
3029 :
3030 : {
3031 : intn i; /* Loop index */
3032 1 : intn status = 0; /* routine return status variable */
3033 :
3034 : int32 fid; /* HDF-EOS file ID */
3035 : int32 sdInterfaceID; /* HDF SDS interface ID */
3036 : int32 sdid; /* SDS ID */
3037 :
3038 : int32 dum; /* Dummy variable */
3039 : int32 rankSDS; /* Rank of SDS/Field/tile */
3040 :
3041 : int32 dims[8]; /* Field/SDS dimensions */
3042 : int32 tileFlags; /* flag to determine if field is tiled */
3043 : HDF_CHUNK_DEF tileDef; /* union holding tiling info. */
3044 :
3045 :
3046 : /* Check if improper gridID */
3047 1 : status = GDchkgdid(gridID, "GDtileinfo", &fid, &sdInterfaceID, &dum);
3048 1 : if (status == 0)
3049 : {
3050 :
3051 : /* Get field info */
3052 1 : status = GDfieldinfo(gridID, fieldname, &rankSDS, dims, &dum, NULL);
3053 :
3054 1 : if (status == 0)
3055 : {
3056 :
3057 : /* Check whether fieldname is in SDS (multi-dim field) */
3058 : /* --------------------------------------------------- */
3059 0 : status = GDSDfldsrch(gridID, sdInterfaceID, fieldname, &sdid,
3060 : &rankSDS, &dum, &dum, dims, &dum);
3061 0 : if (status < 0)
3062 0 : return -1;
3063 :
3064 : /* Query field for tiling information */
3065 0 : status = SDgetchunkinfo(sdid, &tileDef, &tileFlags);
3066 :
3067 : /* If field is untiled, return untiled flag */
3068 0 : if (tileFlags == HDF_NONE)
3069 : {
3070 0 : *tilecode = HDFE_NOTILE;
3071 0 : return (status);
3072 : }
3073 :
3074 : /* IF field is tiled or tiled with compression */
3075 0 : else if ((tileFlags == HDF_CHUNK) ||
3076 0 : (tileFlags == (HDF_CHUNK | HDF_COMP)))
3077 : {
3078 0 : if (tilecode != NULL)
3079 : {
3080 0 : *tilecode = HDFE_TILE;
3081 : }
3082 0 : if (tilerank != NULL)
3083 : {
3084 0 : *tilerank = rankSDS;
3085 : }
3086 0 : if (tiledims != NULL)
3087 : {
3088 : /* Assign size of tile dimensions */
3089 0 : for (i = 0; i < rankSDS; i++)
3090 : {
3091 0 : tiledims[i] = tileDef.chunk_lengths[i];
3092 : }
3093 : }
3094 : }
3095 : }
3096 :
3097 : /* Non-existent fieldname */
3098 : else
3099 : {
3100 1 : HEpush(DFE_GENAPP, "GDtileinfo", __FILE__, __LINE__);
3101 1 : HEreport("Fieldname \"%s\" does not exist.\n", fieldname);
3102 1 : status = -1;
3103 : }
3104 :
3105 : }
3106 1 : return (status);
3107 : }
3108 :
3109 : /***********************************************
3110 : GDreadtile --
3111 : This function reads one tile from a particular field.
3112 :
3113 :
3114 : Author--
3115 : Alexis Zubrow
3116 :
3117 : ********************************************************/
3118 :
3119 : intn
3120 0 : GDreadtile(int32 gridID, const char *fieldname, int32 tilecoords[],
3121 : VOIDP tileData)
3122 : {
3123 0 : char code[] = "r"; /* read tile code */
3124 0 : intn status = 0; /* routine return status variable */
3125 :
3126 0 : status = GDwrrdtile(gridID, fieldname, code, tilecoords, tileData);
3127 :
3128 0 : return (status);
3129 : }
3130 :
3131 : /*----------------------------------------------------------------------------|
3132 : | BEGIN_PROLOG |
3133 : | |
3134 : | FUNCTION: GDsdid |
3135 : | |
3136 : | DESCRIPTION: Returns SD element ID for grid field |
3137 : | |
3138 : | |
3139 : | Return Value Type Units Description |
3140 : | ============ ====== ========= ===================================== |
3141 : | status intn return status (0) SUCCEED, (-1) FAIL |
3142 : | |
3143 : | INPUTS: |
3144 : | gridID int32 grid structure ID |
3145 : | fieldname const char field name |
3146 : | |
3147 : | |
3148 : | OUTPUTS: |
3149 : | sdid int32 SD element ID |
3150 : | |
3151 : | NOTES: |
3152 : | |
3153 : | |
3154 : | Date Programmer Description |
3155 : | ====== ============ ================================================= |
3156 : | Oct 07 Andrey Kiselev Original Programmer |
3157 : | |
3158 : | END_PROLOG |
3159 : -----------------------------------------------------------------------------*/
3160 : intn
3161 6 : GDsdid(int32 gridID, const char *fieldname, int32 *sdid)
3162 : {
3163 : intn status; /* routine return status variable */
3164 : int32 fid; /* HDF-EOS file ID */
3165 : int32 sdInterfaceID; /* HDF SDS interface ID */
3166 : int32 dum; /* Dummy variable */
3167 : int32 dims[H4_MAX_VAR_DIMS]; /* Field/SDS dimensions */
3168 :
3169 6 : status = GDchkgdid(gridID, "GDsdid", &fid, &sdInterfaceID, &dum);
3170 6 : if (status != -1)
3171 : {
3172 6 : status = GDSDfldsrch(gridID, sdInterfaceID, fieldname,
3173 : sdid, &dum, &dum, &dum, dims, &dum);
3174 : }
3175 :
3176 6 : return (status);
3177 : }
|