ocssw  1.0
/disk01/web/ocssw/build/src/libhdfutils/hdf_utils.c (r8087/r7884)
Go to the documentation of this file.
00001 /* =========================================================== */
00002 /* Module hdf_utils.c                                          */
00003 /*                                                             */
00004 /* HDF I/O utilities.                                          */
00005 /*                                                             */ 
00006 /* Written By:                                                 */
00007 /*     Norman Kuring, NASA/GSFC                                */
00008 /*                                                             */
00009 /* Modification History:                                       */
00010 /*     B. A. Franz, SAIC GSC, January 1999,                    */
00011 /*     Moved general utilities from SWl01 to this module.      */
00012 /*     Eliminated global usage of sds_id.                      */
00013 /* =========================================================== */
00014 
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h> 
00018 #include <time.h>
00019 #include <math.h>
00020 #include "hdf_utils.h"
00021 #include "mfhdf.h"
00022 
00023 
00024 /************************************************************************
00025 return the size of the HDF data type in bytes.  Return 0 if not found.
00026 ************************************************************************/
00027 int32 hdf_sizeof(int32 dtype)
00028 {
00029     switch(dtype) {
00030       case DFNT_CHAR8:
00031       case DFNT_UCHAR8:
00032       case DFNT_INT8:
00033       case DFNT_UINT8:
00034       case DFNT_NINT8:
00035       case DFNT_NUINT8:
00036       case DFNT_LINT8:
00037       case DFNT_LUINT8:
00038         return 1;
00039       case DFNT_INT16:
00040       case DFNT_UINT16:
00041       case DFNT_NINT16:
00042       case DFNT_NUINT16:
00043       case DFNT_LINT16:
00044       case DFNT_LUINT16:
00045         return 2;
00046       case DFNT_INT32:
00047       case DFNT_UINT32:
00048       case DFNT_FLOAT32:
00049       case DFNT_NINT32:
00050       case DFNT_NUINT32:
00051       case DFNT_NFLOAT32:
00052       case DFNT_LINT32:
00053       case DFNT_LUINT32:
00054       case DFNT_LFLOAT32:
00055         return 4;
00056       case DFNT_INT64:
00057       case DFNT_UINT64:
00058       case DFNT_FLOAT64:
00059       case DFNT_NINT64:
00060       case DFNT_NUINT64:
00061       case DFNT_NFLOAT64:
00062       case DFNT_LINT64:
00063       case DFNT_LUINT64:
00064       case DFNT_LFLOAT64:
00065         return 8;
00066       default:
00067         return 0;
00068     }
00069     return 0;
00070 }
00071 
00072 
00073 /* -------------------------------------------------------- */
00074 /* Create an SDS using the wrappers for the HDF routines     */
00075 /* -------------------------------------------------------- */
00076 int CreateSDS(
00077 int32 sd_id, 
00078 char *sname,    /* short name */
00079 char *lname,    /* long name */
00080 char *standard_name, /* NetCDF standard name (not set if passed NULL or "") */
00081 char *units,    /* units (not set if passed NULL or "") */
00082 double low,     /* low end of valid range */
00083 double high,    /* high end of range (no range set if low >= high) */
00084 float slope,    /* scale factor (not set if 0)  */
00085 float offset,   /* scaling offset (not set if 0)  */
00086 int32 nt,       /* HDF number type */
00087 int32 rank,     /* number of dimensions (must be <= 3) */
00088 int32 d0,       /* size of 1st dimension */
00089 int32 d1,       /* size of 2nd dimension */
00090 int32 d2,       /* size of 3rd dimension (1 if rank < 2) */
00091 char *dn0,      /* name of 1st dimension */
00092 char *dn1,      /* name of 2nd dimension (NULL if rank < 2) */
00093 char *dn2       /* name of 3rd dimension (NULL if rank < 3) */
00094 ) {
00095 
00096    int32 sds_id;
00097 
00098    if (rank < 3) { d2 = 1; dn2 = NULL; }
00099    if (rank < 2) { d1 = 1; dn1 = NULL; }
00100 
00101    /* Create the SDS */
00102    PTB( sd_create(sd_id, sname, nt, rank, d0, d1, d2, &sds_id) );
00103 
00104    /* Name its dimensions */
00105    if (d0 != SD_UNLIMITED) {
00106        PTB( sd_setdimnames(sds_id, dn0, dn1, dn2) );
00107    } else if (SDsetblocksize(sds_id, 4194304) == FAIL) {
00108        printf("-E- %s line %d: Could not enlarge the HDF block size.\n",__FILE__,__LINE__);
00109        return(HDF_FUNCTION_ERROR);
00110    }
00111 
00112    /* Add a "long_name" attribute */
00113    PTB( sd_setattr( sds_id, "long_name", DFNT_CHAR, strlen(lname)+1, lname) );
00114 
00115    /* Add a "valid_range" attribute if one is specified */
00116    if (low < high) {
00117    switch(nt) {              /* Use the appropriate number type */
00118       case DFNT_UINT8:
00119          {
00120          uint8 vr[2];
00121          vr[0] = (uint8)low;
00122          vr[1] = (uint8)high;
00123          PTB( sd_setattr(sds_id,"valid_range",DFNT_UINT8,2,vr) );
00124          }
00125          break;
00126       case DFNT_INT16:
00127          {
00128          int16 vr[2];
00129          vr[0] = (int16)low;
00130          vr[1] = (int16)high;
00131          PTB( sd_setattr(sds_id,"valid_range",DFNT_INT16,2,vr) );
00132          }
00133          break;
00134       case DFNT_INT32:
00135          {
00136          int32 vr[2];
00137          vr[0] = (int32)low;
00138          vr[1] = (int32)high;
00139          PTB( sd_setattr(sds_id,"valid_range",DFNT_INT32,2,vr) );
00140          }
00141          break;
00142       case DFNT_FLOAT32:
00143          {
00144          float32 vr[2];
00145          vr[0] = (float32)low;
00146          vr[1] = (float32)high;
00147          PTB( sd_setattr(sds_id,"valid_range",DFNT_FLOAT32,2,vr) );
00148          }
00149          break;
00150       default:
00151          fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__);
00152          fprintf(stderr,"Got unsupported number type (%d) ",nt);
00153          fprintf(stderr,"while trying to create SDS, \"%s\", ",sname);
00154          return(PROGRAMMER_BOOBOO);
00155       }
00156    }           
00157 
00158    /* Add a "slope" attribute if one is specified, and also
00159    an intercept attribute */
00160    if (slope != 0) {
00161       float vr[1], intercept[1];
00162       vr[0] = slope;
00163       intercept[0] = 0.0;
00164       PTB( sd_setattr(sds_id, "slope",DFNT_FLOAT,1,vr) );
00165       PTB( sd_setattr(sds_id, "intercept",DFNT_FLOAT,1,intercept) );
00166    }
00167    if (offset != 0) {
00168       float intercept[1];
00169       intercept[0] = offset;
00170       PTB( sd_setattr(sds_id, "intercept",DFNT_FLOAT,1,intercept) );
00171    }
00172 
00173    /* Add a "units" attribute if one is specified */
00174    if(units != NULL && *units != 0) {
00175       PTB( sd_setattr(sds_id,"units",DFNT_CHAR,strlen(units)+1,units) );
00176    }
00177 
00178    /* Add a "standard_name" attribute if one is specified */
00179    if(standard_name != NULL && *standard_name != 0) {
00180       PTB( sd_setattr(sds_id,"standard_name",DFNT_CHAR,strlen(standard_name)+1,standard_name) );
00181    }
00182 
00183    /* Release this SDS */
00184    PTB( sd_endaccess(sds_id) );
00185 
00186    return(LIFE_IS_GOOD);
00187 }
00188 
00189 /************************************************************************
00190 The following functions are just wrappers for the corresponding HDF
00191 functions.
00192 ************************************************************************/
00193 int sd_setattr(int32 id, char *nam, int32 typ, int32 cnt, VOIDP data){
00194   if(SDsetattr(id,nam,typ,cnt,data)){
00195 
00196     fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__);
00197     fprintf(stderr,"SDsetattr(%d,\"%s\",%d,%d,data) failed.  ",
00198              id,nam,typ,cnt);
00199     return(HDF_FUNCTION_ERROR);
00200   }
00201   return(LIFE_IS_GOOD);
00202 }
00203 
00204 int sd_create(
00205 int32   id,
00206 char    *nam,
00207 int32   typ,
00208 int32   rank,
00209 int32   d0,
00210 int32   d1,
00211 int32   d2,
00212 int32   *sds_id
00213 ){
00214   int32 dimsizes[3];
00215   if(rank > 3){
00216     fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__);
00217     fprintf(stderr,"sd_create() expects to be passed a rank <= 3.  ");
00218     return(PROGRAMMER_BOOBOO);
00219   }
00220   dimsizes[0]=d0; dimsizes[1]=d1; dimsizes[2]=d2;
00221   if((*sds_id = SDcreate(id,nam,typ,rank,dimsizes)) == FAIL){
00222     fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__);
00223     fprintf(stderr,"SDcreate(%d,\"%s\",%d,%d,[%d,%d,%d]) failed.  ",
00224     id,nam,typ,rank,d0,d1,d2);
00225     return(HDF_FUNCTION_ERROR);
00226   }
00227   return(LIFE_IS_GOOD);
00228 }
00229 
00230 int sd_endaccess(int32 id){
00231   if(SDendaccess(id)){
00232     fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__);
00233     fprintf(stderr,"SDendaccess(%d) failed.  ",id);
00234     return(HDF_FUNCTION_ERROR);
00235   }
00236   return(LIFE_IS_GOOD);
00237 }
00238 
00239 int sd_setdimnames(int32 id, char *d0, char *d1, char *d2){
00240   PTB( sd_setdimname(id, 0, d0)  );
00241   if(d1 != NULL && *d1 != 0){
00242     PTB( sd_setdimname(id, 1, d1)  );
00243   }
00244   if(d2 != NULL && *d2 != 0){
00245     PTB( sd_setdimname(id, 2, d2)  );
00246   }
00247   return(LIFE_IS_GOOD);
00248 }
00249 
00250 int sd_setdimname(int32 sds_id, int32 dim_number, char *name){
00251   int32 dim_id;
00252   dim_id = SDgetdimid(sds_id, dim_number);
00253   if(dim_id == FAIL){
00254     fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__);
00255     fprintf(stderr,"SDgetdimid(%d,%d) failed.\n",
00256     sds_id,dim_number       );
00257     return(HDF_FUNCTION_ERROR);
00258   }
00259   if(SDsetdimname(dim_id, name)){
00260     fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__);
00261     fprintf(stderr,"SDsetdimname(%d,\"%s\") failed.\n",
00262     dim_id,name);
00263     return(HDF_FUNCTION_ERROR);
00264   }
00265   return(LIFE_IS_GOOD);
00266 }
00267 
00268 int sd_writedata(
00269 int32   sd_id, 
00270 char    *name,
00271 VOIDP   data,
00272 int32   s0,
00273 int32   s1,
00274 int32   s2,
00275 int32   e0,
00276 int32   e1,
00277 int32   e2
00278 ){
00279   int32 sds_id, start[3], edge[3];
00280 
00281   PTB( sd_select(sd_id, name, &sds_id) );
00282   start[0] = s0;        edge[0] = e0;
00283   start[1] = s1;        edge[1] = e1;
00284   start[2] = s2;        edge[2] = e2;
00285   if(SDwritedata(sds_id,start,NULL,edge,data) == FAIL){
00286     fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__);
00287     fprintf(stderr,"SDwritedata(%d,[%d,%d,%d],NULL,[%d,%d,%d],0x%p) ",
00288     sds_id,s0,s1,s2,e0,e1,e2,data);
00289     fprintf(stderr,"failed.\n");
00290     return(HDF_FUNCTION_ERROR);
00291   }
00292   PTB( sd_endaccess(sds_id)  );
00293   return(LIFE_IS_GOOD);
00294 }
00295 
00296 int sd_readdata(
00297 int32   sd_id, 
00298 char    *name,
00299 VOIDP   data,
00300 int32   s0,
00301 int32   s1,
00302 int32   s2,
00303 int32   e0,
00304 int32   e1,
00305 int32   e2
00306 ){
00307   int32 sds_id, start[3], edge[3];
00308 
00309   PTB( sd_select(sd_id, name, &sds_id) );
00310   start[0] = s0;        edge[0] = e0;
00311   start[1] = s1;        edge[1] = e1;
00312   start[2] = s2;        edge[2] = e2;
00313   if(SDreaddata(sds_id,start,NULL,edge,data) == FAIL){
00314     fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__);
00315     fprintf(stderr,"SDreaddata(%d,[%d,%d,%d],NULL,[%d,%d,%d],0x%p) ",
00316     sds_id,s0,s1,s2,e0,e1,e2,data);
00317     fprintf(stderr,"failed.\n");
00318     return(HDF_FUNCTION_ERROR);
00319   }
00320   PTB( sd_endaccess(sds_id)  );
00321   return(LIFE_IS_GOOD);
00322 }
00323 
00324 int sd_select(int32 sd_id, char *name, int32 *sds_id){
00325 
00326   int32 index;
00327 
00328   index = SDnametoindex(sd_id, name);
00329   if(index == FAIL){
00330 /*
00331     fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__);
00332     fprintf(stderr,"SDnametoindex(%d,\"%s\") failed.\n",
00333     sd_id, name);
00334 */
00335     return(HDF_FUNCTION_ERROR);
00336   }
00337   *sds_id = SDselect(sd_id, index);
00338   if(*sds_id == FAIL){
00339     fprintf(stderr,"-E- %s line %d: ",__FILE__,__LINE__);
00340     fprintf(stderr,"SDselect(%d,%d) failed.\n",
00341     sd_id, index);
00342     return(HDF_FUNCTION_ERROR);
00343   }
00344   return(LIFE_IS_GOOD);
00345 }
00346 
00347 /****************************************************************************
00348 Add the named SDS to the Vgroup specified by its Vgroup identifier.
00349 This function uses the global variable sd_id which is set elsewhere
00350 by a call to SDstart().
00351 *****************************************************************************/
00352 int AddSdsToVgroup(int32 sd_id, int32 v_id, char *name){
00353 
00354   int32     sds_ref, sds_id;
00355 
00356   PTB( sd_select(sd_id, name, &sds_id)  );
00357   sds_ref = SDidtoref(sds_id);
00358   if(sds_ref == FAIL){
00359     fprintf(stderr,
00360     "-E- %s line %d: SDidtoref(%d) failed.\n",
00361     __FILE__,__LINE__,sds_id);
00362     return(HDF_FUNCTION_ERROR);
00363   }
00364   if(Vaddtagref(v_id, DFTAG_NDG, sds_ref) == FAIL){
00365     fprintf(stderr,
00366     "-E- %s line %d: Vaddtagref(%d,%d,%d) failed.\n",
00367     __FILE__,__LINE__,v_id,DFTAG_SD,sds_ref); 
00368     return(HDF_FUNCTION_ERROR);
00369   }
00370   return(LIFE_IS_GOOD);
00371 }
00372 
00373 int v_attach(int32 h_id, int32 *v_id){
00374   *v_id = Vattach(h_id, -1, "w");
00375   if(*v_id == FAIL){
00376     fprintf(stderr,
00377     "-E- %s line %d: Vattach(%d,-1,\"w\") failed.\n",
00378     __FILE__,__LINE__,h_id);
00379     return(HDF_FUNCTION_ERROR);
00380   }
00381   return(LIFE_IS_GOOD);
00382 }
00383 
00384 
00385 /* ------------------------------------------------------ */
00386 /* rdSDS() - reads a SDS (scientific data set), and       */
00387 /*           returns the data                             */
00388 /*                                                        */
00389 /* ------------------------------------------------------ */
00390 int rdSDS(
00391 int32 fileID,
00392 char  *sdsname,
00393 int32 start1,         /* 1st dimension of starting point */
00394 int32 start2,         /* 2nd dimension of starting point */
00395 int32 edges1,         /* 1st dim of length of subset( 0 if reading entire SDS) */
00396 int32 edges2,         /* 2nd dim of length of subset */
00397 VOIDP array_data
00398 ){
00399    int32 sds_id, status, numtype;
00400    int32 sds_index, rank, dims[H4_MAX_VAR_DIMS], nattrs;
00401    int32 start[2], edges[2];
00402    char  tmp_sdsname[H4_MAX_NC_NAME];
00403 
00404    start[0] = 0;
00405    start[1] = 0;
00406    edges[0] = 0;
00407    edges[1] = 0;
00408 
00409    /* Get the SDS index */
00410    sds_index = SDnametoindex(fileID,sdsname);
00411 
00412    if (sds_index < 0) {
00413      printf("-E- %s: SDS \"%s\" not found.\n", "rdSDS",sdsname);
00414      status = SDend(fileID);
00415      exit(1);
00416    }
00417 
00418 
00419    /* Select the SDS */
00420    sds_id = SDselect(fileID, sds_index);
00421 
00422    /* Get the rank and number type of the array */
00423    status = SDgetinfo(sds_id, tmp_sdsname, &rank, dims, &numtype, &nattrs);
00424 
00425    /*
00426    if (strcmp(sdsname,"pxl") == 0) {
00427       ncol = dims[0];
00428    }
00429    */
00430 
00431    /* Define the location, pattern and size of the data to read */
00432    /* set 1st dimension */
00433    start[0] = start1;
00434    if (edges1 == 0) {
00435       edges[0] = dims[0];
00436    } else {
00437       edges[0] = edges1;
00438    }
00439    /* if rank > 1, set 2nd dimension */
00440    if (rank > 1) {
00441       start[1] = start2;
00442       if (edges2 == 0) {
00443          edges[1] = dims[1];
00444       } else {
00445          edges[1] = edges2;
00446       }
00447    }
00448 
00449    /* Based on number type, call the corresponding wrapper
00450    for the HDF SDreaddata function */ 
00451    status = SDreaddata(sds_id, start, NULL, edges, array_data);
00452     
00453    /* Terminate access to the array */
00454    status = SDendaccess(sds_id);
00455 
00456    return(0);
00457 }
00458 
00459 /* ------------------------------------------------------ */
00460 /* getDims() - gets a SDS (scientific data set), and      */
00461 /*           returns the dimensions of the data           */
00462 /*                                                        */
00463 /* ------------------------------------------------------ */
00464 int getDims(
00465 int32 fileID,
00466 char sdsname[H4_MAX_NC_NAME],
00467 int32 dims[H4_MAX_VAR_DIMS]
00468 ) {
00469    int32 sds_id, status, numtype;
00470    int32 sds_index, rank, nattrs;
00471    char tmp_sdsname[H4_MAX_NC_NAME];
00472 
00473 
00474    /* Get the SDS index */
00475    sds_index = SDnametoindex(fileID,sdsname);
00476 
00477    /* Check that the SDS exists */
00478    if (sds_index == -1) {
00479          printf("-E- %s:  Error seeking SDS\n",__FILE__);
00480          return(1);
00481    }
00482 
00483    /* Select the SDS */
00484    sds_id = SDselect(fileID, sds_index);
00485 
00486    /* Get the rank and number type of the array */
00487    status = SDgetinfo(sds_id, tmp_sdsname, &rank, dims, &numtype, &nattrs);  
00488 
00489    /* Terminate access to the array */
00490    status = SDendaccess(sds_id);
00491 
00492    return(0);
00493 }
00494 
00495 
00496 /* ------------------------------------------------------ */
00497 /* get_type() - gets a SDS (scientific data set), and     */
00498 /*           returns the data type                        */
00499 /*                                                        */
00500 /* ------------------------------------------------------ */
00501 int get_type(
00502 int32 fileID,
00503 char sdsname[H4_MAX_NC_NAME],
00504 int32 *dtype
00505 ) {
00506    int32 sds_id, status, numtype;
00507    int32 sds_index, rank, nattrs;
00508    char tmp_sdsname[H4_MAX_NC_NAME];
00509    int32 dims[H4_MAX_VAR_DIMS];
00510 
00511    /* Get the SDS index */
00512    sds_index = SDnametoindex(fileID,sdsname);
00513 
00514    /* Check that the SDS exists */
00515    if (sds_index == -1) {
00516          printf("-E- %s:  Error seeking SDS\n",__FILE__);
00517          return(1);
00518    }
00519 
00520    /* Select the SDS */
00521    sds_id = SDselect(fileID, sds_index);
00522 
00523    /* Get the rank and number type of the array */
00524    status = SDgetinfo(sds_id, tmp_sdsname, &rank, dims, dtype, &nattrs);  
00525 
00526    /* Terminate access to the array */
00527    status = SDendaccess(sds_id);
00528 
00529    return(0);
00530 }
00531 
00532 
00533 /* ------------------------------------------------------ */
00534 /* getHDFattr() - gets an HDF SDS attribute or            */
00535 /*              file attribute (if sdsname is "")         */
00536 /*                                                        */
00537 /* ------------------------------------------------------ */
00538 int getHDFattr(
00539 int32 fileID,
00540 char *attrname, 
00541 char *sdsname,
00542 VOIDP data
00543 ){
00544    int32 id, attr_index, sds_index, status;
00545    int32 data_type, count;
00546    char  tmp_attrname[H4_MAX_NC_NAME];
00547    
00548    /* get the SDS identifier for SDS attributes */
00549    if (strcmp(sdsname,"") != 0) {
00550       /* get the # of the SDS from the SDS name */
00551       sds_index = SDnametoindex(fileID,sdsname);
00552 
00553       /* Check that the SDS exists */
00554       if (sds_index == -1) {
00555          printf("-E- %s:  Error seeking SDS\n",__FILE__);
00556          return(1);
00557       }
00558 
00559       id = SDselect(fileID, sds_index);
00560    } else {
00561       /* identifier = fileID for file (global) attributes */
00562       id = fileID;
00563    }
00564 
00565    /* get the attribute index */
00566    attr_index = SDfindattr(id, attrname);
00567    if (attr_index == -1) {
00568       return(-1);
00569    }
00570 
00571    /* get the information about the file attribute */
00572    status = SDattrinfo(id, attr_index, tmp_attrname,
00573                  &data_type, &count);
00574 
00575    /* read the attribute */
00576    status = SDreadattr(id, attr_index, data);   
00577 
00578    /* Terminate access to the SDS */     
00579    if (strcmp(sdsname,"") != 0) {
00580       status = SDendaccess(id);
00581    }
00582    return(0);  
00583 }
00584 
00585 /*-----------------------------------------------------------------------------
00586     Function: rdvdata
00587 
00588     Returns: intn (status)
00589 
00590     Description:
00591         The function rdvdata reads the requested vdata into the given buffer
00592         and returns the status.
00593 
00594     Arguments: (in calling order)
00595       Type         Name      I/O     Description
00596       ----         ----      ---     -----------
00597       int32        vskey      I      ID number of the vdata
00598       char *       fields     I      field names of the data to read
00599       int32        start      I      start element position
00600       int32        nelt       I      number of elements to read
00601       uchar *      databuf    O      buffer to read the data
00602 
00603     Notes:
00604 
00605     Modification history:
00606           Programmer     Organization      Date      Description of change
00607         --------------   ------------    --------    ---------------------
00608         Lakshmi Kumar    Hughes STX      03/11/94    Original development
00609 
00610 ------------------------------------------------------------------------------*/
00611 intn rdvdata(int32 vskey, char *fields, int32 start, int32 nelt,
00612                 unsigned char *databuf)
00613 {
00614   int32  ret;
00615 
00616   if ((ret=VSsetfields(vskey, fields)) < 0)
00617         return FAIL; 
00618 
00619   if ((ret = VSseek(vskey, start)) < 0)
00620         return FAIL;
00621 
00622   if ((ret = VSread(vskey, databuf, nelt, FULL_INTERLACE)) < 0)
00623         return FAIL;
00624 
00625   return ret;
00626 
00627 }
00628 
00629 /*-----------------------------------------------------------------------------
00630     Function: attach_vdata
00631 
00632     Returns: intn (Status)
00633 
00634     Description:
00635         The function attach_vdata attaches to the requested vdata
00636 
00637     Arguments: (in calling order)
00638       Type       Name        I/O     Description
00639       ----       ----        ---     -----------
00640       int32      fid          I      HDF file ID
00641       char *     sname        I      vdata name
00642 
00643     Notes:
00644 
00645     Modification history:
00646           Programmer     Organization      Date      Description of change
00647         --------------   ------------    --------    ---------------------
00648         Lakshmi Kumar    Hughes STX      03/11/94    Original development
00649 
00650 
00651 ------------------------------------------------------------------------------*/
00652 intn attach_vdata(int32 fid, char *sname)
00653 {
00654    int32 vsid, vskey;
00655 
00656    vsid = VSfind(fid, sname);
00657    if ((vskey = VSattach(fid, vsid, "r")) < 0)
00658       return FAIL;
00659    return vskey;
00660 }
00661 
00662 /*-----------------------------------------------------------------------------
00663     Function: read_SDS
00664 
00665     Returns: intn (status)
00666 
00667     Description:
00668         The function read_SDS reads the requested SDS/NDG into the given 
00669     buffer and returns the status.
00670 
00671     Arguments: (in calling order)
00672       Type         Name      I/O     Description
00673       ----         ----      ---     -----------
00674       int32        sdfid      I      ID number 
00675       char *       sds_name   I      SDS name
00676       void *       buffer     O      data buffer  
00677 
00678     Notes:
00679 
00680     Modification history:
00681           Programmer     Organization      Date      Description of change
00682         --------------   ------------    --------    ---------------------
00683         Lakshmi Kumar    Hughes STX      06/07/94    Original development
00684 
00685 ------------------------------------------------------------------------------*/
00686 int32 read_SDS(int32 sdfid, char *sds_name, void *buffer)
00687 {
00688 
00689    int32 index, sdsid, rank, numbertype, nattrs; 
00690    int32 dimsizes[2], start[2];
00691    char  name[255];
00692 
00693    start[0]=start[1] = 0;
00694 
00695    if ((index = SDnametoindex(sdfid, sds_name)) < 0)
00696       return -2;
00697 
00698    if ((sdsid = SDselect(sdfid, index)) < 0)
00699       return -2;
00700 
00701    if ((SDgetinfo(sdsid, name, &rank, dimsizes, &numbertype, &nattrs)) < 0)
00702       return -2;
00703   
00704    if ((SDreaddata(sdsid, start, NULL, dimsizes, buffer)) < 0)
00705       return -2;
00706 
00707    if ((SDendaccess(sdsid)) < 0)
00708       return -2;
00709 
00710    return SUCCEED;
00711 } 
00712 
00713 
00714 /* ------------------------------------------------------ */
00715 /* GetFileDesc() - reads the HDF file descriptions into   */
00716 /*                 a buffer.                              */
00717 /*                                                        */
00718 /* ------------------------------------------------------ */
00719 char *GetFileDesc(char *filename)
00720 {
00721    static char *desc_buffer = NULL;
00722    int32 file_id, desc_length, fds_len;
00723    int status;
00724 
00725    /* Open the file */
00726    file_id = Hopen(filename, DFACC_READ, 0);
00727 
00728    /* Get the length of the file description */
00729    desc_length = DFANgetfdslen(file_id,1);
00730    if (desc_length == 0)
00731        return(desc_buffer);
00732 
00733    /* Create a buffer for the file description */
00734    desc_buffer = HDgetspace(desc_length);
00735    if (desc_buffer == NULL)
00736        return(desc_buffer);
00737    /* Read the file description */
00738    fds_len = DFANgetfds(file_id, desc_buffer, desc_length, 1);
00739    if (fds_len == 0)
00740        return(desc_buffer);
00741 
00742    /* Add ';' if not last non-whitespace character */
00743    while (desc_buffer[fds_len] <= 32) fds_len--;
00744    if (desc_buffer[fds_len] != ';') desc_buffer[fds_len+1] = ';';
00745 
00746    /* Close the file */
00747    status = Hclose(file_id);
00748 
00749    return(desc_buffer);
00750 }
00751 
00752