LCOV - code coverage report
Current view: directory - frmts/grib/degrib18/g2clib-1.0.4 - g2_addgrid.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 86 0 0.0 %
Date: 2012-04-28 Functions: 1 0 0.0 %

       1                 : #include <stdio.h>
       2                 : #include <stdlib.h>
       3                 : #include "grib2.h"
       4                 : 
       5                 : 
       6               0 : g2int g2_addgrid(unsigned char *cgrib,g2int *igds,g2int *igdstmpl,g2int *ideflist,g2int idefnum)
       7                 : //$$$  SUBPROGRAM DOCUMENTATION BLOCK
       8                 : //                .      .    .                                       .
       9                 : // SUBPROGRAM:    g2_addgrid 
      10                 : //   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-11-01
      11                 : //
      12                 : // ABSTRACT: This routine packs up a Grid Definition Section (Section 3) 
      13                 : //   and adds it to a GRIB2 message.  It is used with routines "g2_create",
      14                 : //   "g2_addlocal", "g2_addfield",
      15                 : //   and "g2_gribend" to create a complete GRIB2 message.
      16                 : //   g2_create must be called first to initialize a new GRIB2 message.
      17                 : //
      18                 : // PROGRAM HISTORY LOG:
      19                 : // 2002-11-01  Gilbert
      20                 : //
      21                 : // USAGE:    int g2_addgrid(unsigned char *cgrib,g2int *igds,g2int *igdstmpl,
      22                 : //                          g2int *ideflist,g2int idefnum)
      23                 : //   INPUT ARGUMENTS:
      24                 : //     cgrib    - Char array that contains the GRIB2 message to which
      25                 : //                section should be added.
      26                 : //     igds     - Contains information needed for GRIB Grid Definition Section 3
      27                 : //                Must be dimensioned >= 5.
      28                 : //                igds[0]=Source of grid definition (see Code Table 3.0)
      29                 : //                igds[1]=Number of grid points in the defined grid.
      30                 : //                igds[2]=Number of octets needed for each 
      31                 : //                            additional grid points definition.  
      32                 : //                            Used to define number of
      33                 : //                            points in each row ( or column ) for
      34                 : //                            non-regular grids.  
      35                 : //                            = 0, if using regular grid.
      36                 : //                igds[3]=Interpretation of list for optional points 
      37                 : //                            definition.  (Code Table 3.11)
      38                 : //                igds[4]=Grid Definition Template Number (Code Table 3.1)
      39                 : //     igdstmpl - Contains the data values for the specified Grid Definition
      40                 : //                Template ( NN=igds[4] ).  Each element of this integer 
      41                 : //                array contains an entry (in the order specified) of Grid
      42                 : //                Defintion Template 3.NN
      43                 : //     ideflist - (Used if igds[2] != 0)  This array contains the
      44                 : //                number of grid points contained in each row ( or column )
      45                 : //      idefnum - (Used if igds[2] != 0)  The number of entries
      46                 : //                in array ideflist.  i.e. number of rows ( or columns )
      47                 : //                for which optional grid points are defined.
      48                 : //
      49                 : //   OUTPUT ARGUMENTS:      
      50                 : //     cgrib    - Char array to contain the updated GRIB2 message.
      51                 : //                Must be allocated large enough to store the entire
      52                 : //                GRIB2 message.
      53                 : //
      54                 : //   RETURN VALUES:
      55                 : //     ierr     - Return code.
      56                 : //              > 0 = Current size of updated GRIB2 message
      57                 : //               -1 = GRIB message was not initialized.  Need to call
      58                 : //                    routine gribcreate first.
      59                 : //               -2 = GRIB message already complete.  Cannot add new section.
      60                 : //               -3 = Sum of Section byte counts doesn't add to total byte count
      61                 : //               -4 = Previous Section was not 1, 2 or 7.
      62                 : //               -5 = Could not find requested Grid Definition Template.
      63                 : //
      64                 : // REMARKS: Note that the Grid Def Section ( Section 3 ) can only follow
      65                 : //          Section 1, 2 or Section 7 in a GRIB2 message.
      66                 : //
      67                 : // ATTRIBUTES:
      68                 : //   LANGUAGE: C
      69                 : //   MACHINE:  
      70                 : //
      71                 : //$$$
      72                 : {
      73                 : 
      74                 :       g2int ierr;
      75                 :       static unsigned char G=0x47;       // 'G'
      76                 :       static unsigned char R=0x52;       // 'R'
      77                 :       static unsigned char I=0x49;       // 'I'
      78                 :       static unsigned char B=0x42;       // 'B'
      79                 :       static unsigned char seven=0x37;   // '7'
      80                 : 
      81                 :       static g2int one=1,three=3,miss=65535;
      82                 :       g2int   lensec3,iofst,ibeg,lencurr,len;
      83                 :       g2int   i,j,temp,ilen,isecnum,nbits;
      84               0 :       xxtemplate *mapgrid=0;
      85                 :  
      86               0 :       ierr=0;
      87                 : //
      88                 : //  Check to see if beginning of GRIB message exists
      89                 : //
      90               0 :       if ( cgrib[0]!=G || cgrib[1]!=R || cgrib[2]!=I || cgrib[3]!=B ) {
      91               0 :         printf("g2_addgrid: GRIB not found in given message.\n");
      92               0 :         printf("g2_addgrid: Call to routine gribcreate required to initialize GRIB messge.\n");
      93               0 :         ierr=-1;
      94               0 :         return(ierr);
      95                 :       }
      96                 : //
      97                 : //  Get current length of GRIB message
      98                 : //  
      99               0 :       gbit(cgrib,&lencurr,96,32);
     100                 : //
     101                 : //  Check to see if GRIB message is already complete
     102                 : //  
     103               0 :       if ( cgrib[lencurr-4]==seven && cgrib[lencurr-3]==seven &&
     104               0 :            cgrib[lencurr-2]==seven && cgrib[lencurr-1]==seven ) {
     105               0 :         printf("g2_addgrid: GRIB message already complete.  Cannot add new section.\n");
     106               0 :         ierr=-2;
     107               0 :         return(ierr);
     108                 :       }
     109                 : //
     110                 : //  Loop through all current sections of the GRIB message to
     111                 : //  find the last section number.
     112                 : //
     113               0 :       len=16;    // length of Section 0
     114                 :       for (;;) { 
     115                 :       //    Get section number and length of next section
     116               0 :         iofst=len*8;
     117               0 :         gbit(cgrib,&ilen,iofst,32);
     118               0 :         iofst=iofst+32;
     119               0 :         gbit(cgrib,&isecnum,iofst,8);
     120               0 :         len=len+ilen;
     121                 :       //    Exit loop if last section reached
     122               0 :         if ( len == lencurr ) break;
     123                 :       //    If byte count for each section doesn't match current
     124                 :       //    total length, then there is a problem.
     125               0 :         if ( len > lencurr ) {
     126               0 :           printf("g2_addgrid: Section byte counts don''t add to total.\n");
     127               0 :           printf("g2_addgrid: Sum of section byte counts = %d\n",len);
     128               0 :           printf("g2_addgrid: Total byte count in Section 0 = %d\n",lencurr);
     129               0 :           ierr=-3;
     130               0 :           return(ierr);
     131                 :         }
     132               0 :       }
     133                 : //
     134                 : //  Section 3 can only be added after sections 1, 2 and 7.
     135                 : //
     136               0 :       if ( (isecnum!=1) && (isecnum!=2) && (isecnum!=7) ) {
     137               0 :         printf("g2_addgrid: Section 3 can only be added after Section 1, 2 or 7.\n");
     138               0 :         printf("g2_addgrid: Section ',isecnum,' was the last found in given GRIB message.\n");
     139               0 :         ierr=-4;
     140               0 :         return(ierr);
     141                 :       }
     142                 : //
     143                 : //  Add Section 3  - Grid Definition Section
     144                 : //
     145               0 :       ibeg=lencurr*8;        //   Calculate offset for beginning of section 3
     146               0 :       iofst=ibeg+32;         //   leave space for length of section
     147               0 :       sbit(cgrib,&three,iofst,8);     // Store section number ( 3 )
     148               0 :       iofst=iofst+8;
     149               0 :       sbit(cgrib,igds+0,iofst,8);     // Store source of Grid def.
     150               0 :       iofst=iofst+8;
     151               0 :       sbit(cgrib,igds+1,iofst,32);    // Store number of data pts.
     152               0 :       iofst=iofst+32;
     153               0 :       sbit(cgrib,igds+2,iofst,8);     // Store number of extra octets.
     154               0 :       iofst=iofst+8;
     155               0 :       sbit(cgrib,igds+3,iofst,8);     // Store interp. of extra octets.
     156               0 :       iofst=iofst+8;
     157                 :       //   if Octet 6 is not equal to zero, Grid Definition Template may
     158                 :       //   not be supplied.
     159               0 :       if ( igds[0] == 0 )
     160               0 :         sbit(cgrib,igds+4,iofst,16);  // Store Grid Def Template num.
     161                 :       else
     162               0 :         sbit(cgrib,&miss,iofst,16);   // Store missing value as Grid Def Template num.
     163               0 :       iofst=iofst+16;
     164                 :       //
     165                 :       //   Get Grid Definition Template
     166                 :       //
     167               0 :       if (igds[0] == 0) {
     168               0 :         mapgrid=getgridtemplate(igds[4]);
     169               0 :         if (mapgrid == 0) {       // undefined template
     170               0 :           ierr=-5;
     171               0 :           return(ierr);
     172                 :         }
     173                 :         //
     174                 :         //   Extend the Grid Definition Template, if necessary.
     175                 :         //   The number of values in a specific template may vary
     176                 :         //   depending on data specified in the "static" part of the
     177                 :         //   template.
     178                 :         //
     179               0 :         if ( mapgrid->needext ) {
     180               0 :           free(mapgrid);
     181               0 :           mapgrid=extgridtemplate(igds[4],igdstmpl);
     182                 :         }
     183                 :       }
     184                 :       //
     185                 :       //   Pack up each input value in array igdstmpl into the
     186                 :       //   the appropriate number of octets, which are specified in
     187                 :       //   corresponding entries in array mapgrid.
     188                 :       //
     189               0 :       for (i=0;i<mapgrid->maplen;i++) {
     190               0 :         nbits=abs(mapgrid->map[i])*8;
     191               0 :         if ( (mapgrid->map[i] >= 0) || (igdstmpl[i] >= 0) )
     192               0 :           sbit(cgrib,igdstmpl+i,iofst,nbits);
     193                 :         else {
     194               0 :           sbit(cgrib,&one,iofst,1);
     195               0 :           temp=abs(igdstmpl[i]);
     196               0 :           sbit(cgrib,&temp,iofst+1,nbits-1);
     197                 :         }
     198               0 :         iofst=iofst+nbits;
     199                 :       }
     200                 :       //  Pack template extension, if appropriate
     201               0 :       j=mapgrid->maplen;
     202               0 :       if ( mapgrid->needext && (mapgrid->extlen > 0) ) {
     203               0 :          for (i=0;i<mapgrid->extlen;i++) {
     204               0 :            nbits=abs(mapgrid->ext[i])*8;
     205               0 :            if ( (mapgrid->ext[i] >= 0) || (igdstmpl[j] >= 0) )
     206               0 :              sbit(cgrib,igdstmpl+j,iofst,nbits);
     207                 :            else {
     208               0 :              sbit(cgrib,&one,iofst,1);
     209               0 :              temp=abs(igdstmpl[j]);
     210               0 :              sbit(cgrib,&temp,iofst+1,nbits-1);
     211                 :            }
     212               0 :            iofst=iofst+nbits;
     213               0 :            j++;
     214                 :          }
     215                 :       }
     216               0 :       free(mapgrid);
     217                 :       //
     218                 :       //   If requested,
     219                 :       //   Insert optional list of numbers defining number of points
     220                 :       //   in each row or column.  This is used for non regular
     221                 :       //   grids.
     222                 :       //
     223               0 :       if ( igds[2] != 0 ) {
     224               0 :          nbits=igds[2]*8;
     225               0 :          sbits(cgrib,ideflist,iofst,nbits,0,idefnum);
     226               0 :          iofst=iofst+(nbits*idefnum);
     227                 :       }
     228                 :       //
     229                 :       //   Calculate length of section 3 and store it in octets
     230                 :       //   1-4 of section 3.
     231                 :       //
     232               0 :       lensec3=(iofst-ibeg)/8;
     233               0 :       sbit(cgrib,&lensec3,ibeg,32);
     234                 : 
     235                 : //
     236                 : //  Update current byte total of message in Section 0
     237                 : //
     238               0 :       lencurr+=lensec3;
     239               0 :       sbit(cgrib,&lencurr,96,32);
     240                 : 
     241               0 :       return(lencurr);
     242                 : 
     243                 : }

Generated by: LCOV version 1.7