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