                             GRIB2 USERS GUIDE (C)

Contents:

- Introduction
- GRIB2 Tables/Templates
- GRIB2 Encoding Routines
- GRIB2 Decoding Routines
- Decoding all GRIB2 Fields in a File
- Extracting Selected GRIB2 Fields from a GRIB2 file
- GRIB2 Routine Documentation

===============================================================================
 
                                Introduction

This document briefly describes the routines available for encoding/decoding
GRIB Edition 2 (GRIB2) messages.   A basic familiarity with GRIB is assumed. 

A GRIB Edition 2 message is a machine independent format for storing
one or more gridded data fields.   Each GRIB2 message consists of the 
following sections:

SECTION 0 - Indicator Section
SECTION 1 - Identification Section
SECTION 2 - (Local Use Section) - optional                           }
SECTION 3 - Grid Definition Section                     }            }
SECTION 4 - Product Definition Section    }             }            }(repeated)
SECTION 5 - Data Representation Section   }             }(repeated)  }
SECTION 6 - Bit-map Section               }(repeated)   }            }
SECTION 7 - Data Section                  }             }            }
SECTION 8 - End Section                   }             }            }

Sequences of GRIB sections 2 to 7, 3 to 7, or sections 4 to 7 may be repeated
within a single GRIB message.   All sections within such repeated sequences
must be present and shall appear in the numerical order noted above. 
Unrepeated sections remain in effect until redefined. 

The above overview was taken from WMO's FM 92-XII GRIB description
of the GRIB Edition 2 form. 

===============================================================================

                         GRIB2 Tables/Templates

WMO's GRIB2 specification "FM 92-XII GRIB - General Regularly-distributed
Information in Binary Form" contains descriptions of each template
and code table information.   This document can be found at
http://www.wmo.ch/web/www/WMOCodes.html
(PDF and MSWord formats are available)

===============================================================================

                          GRIB2 Encoding Routines

Since a GRIB2 message can contain gridded fields for many parameters on
a number of different grids, several routines are used to encode a message. 
This should give users more flexibility in how to organize data
within one or more GRIB2 messages. 

To start a new GRIB2 message, call function g2_create.   G2_create 
encodes Sections 0 and 1 at the beginning of the message.   This routine 
must be used to create each message. 

Routine g2_addlocal can be used to add a Local Use Section ( Section 2 ). 
Note that this section is optional and need not appear in a GRIB2 message. 

Function g2_addgrid is used to encode a grid definition into Section 3. 
This grid definition defines the geometry of the the data values in the
fields that follow it.   g2_addgrid can be called again to change the grid 
definition describing subsequent data fields. 

Each data field is added to the GRIB2 message using routine g2_addfield,
which adds Sections 4, 5, 6, and 7 to the message. 

After all desired data fields have been added to the GRIB2 message, a
call to function g2_gribend is needed to add the final section 8 to the
message and to update the length of the message.   A call to g2_gribend
is required for each GRIB2 message. 

Please see the "GRIB2 Routine Documentation" section below for subroutine
argument usage for the routines mentioned above. 

===============================================================================

                      GRIB2 Decoding Routines

Routine g2_info can be used to find out how many Local Use sections
and data fields are contained in a given GRIB2 message.   This routine also
returns all the information stored in Sections 0 and 1 of the GRIB2
message. 

g2_getfld can be used to get all information pertaining to the nth 
data field in the message.   The subroutine returns all the unpacked metadata
for each Section and Template in a gribfield structure,
which is defined in include file grib2.h.   An option exists that lets the
user decide if the decoder should unpack the Bit-map ( if applicable ) 
and the data values or just return the field description information. 

Note that a struct gribfield is allocated by g2_getfld, and it also 
contains pointers to many arrays of data that are alloated during decoding. 
Because of this, users are encouraged to free up this memory, when it is 
no longer needed, by an explicit call to routine g2_free. 

Please see the "GRIB2 Routine Documentation" section below for subroutine
argument usage for the routines mentioned above. 

===============================================================================
                     Decoding all GRIB2 Fields in a File

Routines seekgb, g2_info and g2_getfld can be used to sequentially decode
all the GRIB2 fields in a file.   This is illustrated by the following example:

    #include <stdio.h>
    #include <stdlib.h>
    #include "grib2.h"

    unsigned char *cgrib;
    g2int  listsec0[3],listsec1[13],numlocal,numfields;
    long   lskip,n,lgrib,iseek;
    int    unpack,ret,ierr;
    gribfield  *gfld;
    FILE   *fptr;
    size_t  lengrib;
 
    iseek=0;
    unpack=1;
    expand=1;
    fptr=fopen("inputgribfile","r");
    for (;;) {
         seekgb(fptr,iseek,32000,&lskip,&lgrib);
         if (lgrib == 0) break;    // end loop at EOF or problem
         cgrib=(unsigned char *)malloc(lgrib);
         ret=fseek(fptr,lskip,SEEK_SET);
         lengrib=fread(cgrib,sizeof(unsigned char),lgrib,fptr);
         iseek=lskip+lgrib;
         ierr=g2_info(cgrib,listsec0,listsec1,&numfields,&numlocal);
         for (n=0;n<numfields;n++) {
            ierr=g2_getfld(cgrib,n+1,unpack,expand,&gfld);
                . 
                .   // Process Field Here
                . 
            g2_free(gfld);
         }
         free(cgrib);
    }


===============================================================================

                Extracting Selected GRIB2 Fields from a GRIB2 File

   This feature not implemented in the "C" version of the GRIB2
   library yet. 

===============================================================================

                       GRIB2 Routine Documentation

//////////////////  grib2.h  ///////////////////////////////////////////
//                .       .     .                                        . 
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-10-25
//
//   Each element of structure gribfield is defined as:
//   
//   gribfield gfld;
//
//        gfld->version = GRIB edition number ( currently 2 )
//        gfld->discipline = Message Discipline ( see Code Table 0.0 )
//        gfld->idsect = Contains the entries in the Identification
//                        Section ( Section 1 )
//                        This element is a pointer to an array
//                        that holds the data. 
//            gfld->idsect[0]  = Identification of originating Centre
//                                    ( see Common Code Table C-1 )
//                             7 - US National Weather Service
//            gfld->idsect[1]  = Identification of originating Sub-centre
//            gfld->idsect[2]  = GRIB Master Tables Version Number
//                                    ( see Code Table 1.0 )
//                             0 - Experimental
//                             1 - Initial operational version number
//            gfld->idsect[3]  = GRIB Local Tables Version Number
//                                    ( see Code Table 1.1 )
//                             0     - Local tables not used
//                             1-254 - Number of local tables version used
//            gfld->idsect[4]  = Significance of Reference Time (Code Table 1.2)
//                             0 - Analysis
//                             1 - Start of forecast
//                             2 - Verifying time of forecast
//                             3 - Observation time
//            gfld->idsect[5]  = Year ( 4 digits )
//            gfld->idsect[6]  = Month
//            gfld->idsect[7)  = Day
//            gfld->idsect[8]  = Hour
//            gfld->idsect[9]  = Minute
//            gfld->idsect[10]  = Second
//            gfld->idsect[11]  = Production status of processed data
//                                    ( see Code Table 1.3 )
//                              0 - Operational products
//                              1 - Operational test products
//                              2 - Research products
//                              3 - Re-analysis products
//            gfld->idsect[12]  = Type of processed data ( see Code Table 1.4 )
//                              0  - Analysis products
//                              1  - Forecast products
//                              2  - Analysis and forecast products
//                              3  - Control forecast products
//                              4  - Perturbed forecast products
//                              5  - Control and perturbed forecast products
//                              6  - Processed satellite observations
//                              7  - Processed radar observations
//        gfld->idsectlen = Number of elements in gfld->idsect[]. 
//        gfld->local   = Pointer to character array containing contents
//                       of Local Section 2, if included
//        gfld->locallen = length of array gfld->local[]
//        gfld->ifldnum = field number within GRIB message
//        gfld->griddef = Source of grid definition (see Code Table 3.0)
//                      0 - Specified in Code table 3.1
//                      1 - Predetermined grid Defined by originating centre
//        gfld->ngrdpts = Number of grid points in the defined grid. 
//        gfld->numoct_opt = Number of octets needed for each
//                          additional grid points definition. 
//                          Used to define number of
//                          points in each row ( or column ) for
//                          non-regular grids. 
//                          = 0, if using regular grid. 
//        gfld->interp_opt = Interpretation of list for optional points
//                          definition.   (Code Table 3.11)
//        gfld->igdtnum = Grid Definition Template Number (Code Table 3.1)
//        gfld->igdtmpl  = Contains the data values for the specified Grid
//                         Definition Template ( NN=gfld->igdtnum ).   Each
//                         element of this integer array contains an entry (in
//                         the order specified) of Grid Defintion Template 3.NN
//                         This element is a pointer to an array
//                         that holds the data. 
//        gfld->igdtlen = Number of elements in gfld->igdtmpl[].   i.e. number of
//                       entries in Grid Defintion Template 3.NN
//                       ( NN=gfld->igdtnum ). 
//        gfld->list_opt  = (Used if gfld->numoct_opt .ne.  0)  This array
//                          contains the number of grid points contained in
//                          each row ( or column ).   (part of Section 3)
//                          This element is a pointer to an array
//                          that holds the data.   This pointer is nullified
//                          if gfld->numoct_opt=0. 
//        gfld->num_opt = (Used if gfld->numoct_opt .ne.  0) 
//                       The number of entries
//                       in array ideflist.   i.e. number of rows ( or columns )
//                       for which optional grid points are defined.   This value
//                       is set to zero, if gfld->numoct_opt=0. 
//        gfdl->ipdtnum = Product Definition Template Number(see Code Table 4.0)
//        gfld->ipdtmpl  = Contains the data values for the specified Product
//                         Definition Template ( N=gfdl->ipdtnum ).  Each element
//                         of this integer array contains an entry (in the
//                         order specified) of Product Defintion Template 4.N.
//                         This element is a pointer to an array
//                         that holds the data. 
//        gfld->ipdtlen = Number of elements in gfld->ipdtmpl[].   i.e. number of
//                       entries in Product Defintion Template 4.N
//                       ( N=gfdl->ipdtnum ). 
//        gfld->coord_list  = Real array containing floating point values
//                            intended to document the vertical discretisation
//                            associated to model data on hybrid coordinate
//                            vertical levels.   (part of Section 4)
//                            This element is a pointer to an array
//                            that holds the data. 
//        gfld->num_coord = number of values in array gfld->coord_list[]. 
//        gfld->ndpts = Number of data points unpacked and returned. 
//        gfld->idrtnum = Data Representation Template Number
//                       ( see Code Table 5.0)
//        gfld->idrtmpl  = Contains the data values for the specified Data
//                         Representation Template ( N=gfld->idrtnum ).   Each
//                         element of this integer array contains an entry
//                         (in the order specified) of Product Defintion
//                         Template 5.N.
//                         This element is a pointer to an array
//                         that holds the data. 
//        gfld->idrtlen = Number of elements in gfld->idrtmpl[].   i.e. number
//                       of entries in Data Representation Template 5.N
//                       ( N=gfld->idrtnum ). 
//        gfld->unpacked = logical value indicating whether the bitmap and
//                        data values were unpacked.   If false,
//                        gfld->bmap and gfld->fld pointers are nullified. 
//        gfld->expanded = Logical value indicating whether the data field
//                         was expanded to the grid in the case where a
//                         bit-map is present.   If true, the data points in
//                         gfld->fld match the grid points and zeros were
//                         inserted at grid points where data was bit-mapped
//                         out.   If false, the data values in gfld->fld were
//                         not expanded to the grid and are just a consecutive
//                         array of data points corresponding to each value of
//                         "1" in gfld->bmap. 
//        gfld->ibmap = Bitmap indicator ( see Code Table 6.0 )
//                     0 = bitmap applies and is included in Section 6. 
//                     1-253 = Predefined bitmap applies
//                     254 = Previously defined bitmap applies to this field
//                     255 = Bit map does not apply to this product. 
//        gfld->bmap  = integer array containing decoded bitmap,
//                      if gfld->ibmap=0 or gfld->ibap=254.   
//                      Otherwise nullified. 
//                      This element is a pointer to an array
//                      that holds the data. 
//        gfld->fld  = Array of gfld->ndpts unpacked data points. 
//                     This element is a pointer to an array
//                     that holds the data. 
///////////////////////////////////////////////////////////////////////////



//$$$  SUBPROGRAM DOCUMENTATION BLOCK ////////////////////////////////////
//
// SUBPROGRAM: seekgb         Searches a file for the next GRIB message. 
//   PRGMMR: Gilbert          ORG: W/NP11      DATE: 2002-10-28
//
// ABSTRACT: This subprogram searches a file for the next GRIB Message. 
//   The search is done starting at byte offset iseek of the file referenced 
//   by lugb for mseek bytes at a time. 
//   If found, the starting position and length of the message are returned
//   in lskip and lgrib, respectively. 
//   The search is terminated when an EOF or I/O error is encountered. 
//
// PROGRAM HISTORY LOG:
// 2002-10-28  GILBERT   Modified from Iredell's skgb subroutine
//
// USAGE:    seekgb(FILE *lugb,long iseek,long mseek,int *lskip,int *lgrib)
//   INPUT ARGUMENTS:
//     lugb       - FILE pointer for the file to search.   File must be
//                  opened before this routine is called. 
//     iseek      - number of bytes in the file to skip before search
//     mseek      - number of bytes to search at a time
//   OUTPUT ARGUMENTS:
//     lskip      - number of bytes to skip from the beggining of the file
//                  to where the GRIB message starts
//     lgrib      - number of bytes in message (set to 0, if no message found)
//
// ATTRIBUTES:
//   LANGUAGE: C
//
//////////////////////////////////////////////////////////////////////////



//$$$  SUBPROGRAM DOCUMENTATION BLOCK  ///////////////////////////////////
//                .       .     .                                        . 
// SUBPROGRAM:    g2_info 
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-10-28
//
// ABSTRACT: This subroutine searches through a GRIB2 message and
//   returns the number of gridded fields found in the message and
//   the number (and maximum size) of Local Use Sections. 
//   Also various checks  are performed
//   to see if the message is a valid GRIB2 message. 
//
// PROGRAM HISTORY LOG:
// 2002-10-28  Gilbert
//
// USAGE:   int g2_info(unsigned char *cgrib,g2int *listsec0,g2int *listsec1,
//            g2int *numfields,g2int *numlocal)
//   INPUT ARGUMENT:
//     cgrib    - Character pointer to the GRIB2 message
//
//   OUTPUT ARGUMENTS:      
//     listsec0 - pointer to an array containing information decoded from 
//                GRIB Indicator Section 0. 
//                Must be allocated with >= 3 elements. 
//                listsec0[0]=Discipline-GRIB Master Table Number
//                            (see Code Table 0.0)
//                listsec0[1]=GRIB Edition Number (currently 2)
//                listsec0[2]=Length of GRIB message
//     listsec1 - pointer to an array containing information read from GRIB 
//                Identification Section 1. 
//                Must be allocated with >= 13 elements. 
//                listsec1[0]=Id of orginating centre (Common Code Table C-1)
//                listsec1[1]=Id of orginating sub-centre (local table)
//                listsec1[2]=GRIB Master Tables Version Number (Code Table 1.0)
//                listsec1[3]=GRIB Local Tables Version Number 
//                listsec1[4]=Significance of Reference Time (Code Table 1.1)
//                listsec1[5]=Reference Time - Year (4 digits)
//                listsec1[6]=Reference Time - Month
//                listsec1[7]=Reference Time - Day
//                listsec1[8]=Reference Time - Hour
//                listsec1[9]=Reference Time - Minute
//                listsec1[10]=Reference Time - Second
//                listsec1[11]=Production status of data (Code Table 1.2)
//                listsec1[12]=Type of processed data (Code Table 1.3)
//     numfields- The number of gridded fields found in the GRIB message. 
//                That is, the number of occurences of Sections 4 - 7. 
//     numlocal - The number of Local Use Sections ( Section 2 ) found in 
//                the GRIB message. 
//
//     RETURN VALUES:
//     ierr     - Error return code. 
//                0 = no error
//                1 = Beginning characters "GRIB" not found. 
//                2 = GRIB message is not Edition 2. 
//                3 = Could not find Section 1, where expected. 
//                4 = End string "7777" found, but not where expected. 
//                5 = End string "7777" not found at end of message. 
//                6 = Invalid section number found. 
//
// REMARKS: None
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:  
//
//////////////////////////////////////////////////////////////////////////



//$$$  SUBPROGRAM DOCUMENTATION BLOCK  ///////////////////////////////////
//                .       .     .                                        . 
// SUBPROGRAM:    g2_getfld 
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-10-28
//
// ABSTRACT: This subroutine returns all the metadata, template values, 
//   Bit-map ( if applicable ), and the unpacked data for a given data
//   field.   All of the information returned is stored in a gribfield
//   structure, which is defined in file grib2.h. 
//   Users of this routine will need to include "grib2.h" in their source
//   code that calls this routine.   Each component of the gribfield
//   struct is also described in the OUTPUT ARGUMENTS section below. 
//
//   Since there can be multiple data fields packed into a GRIB2
//   message, the calling routine indicates which field is being requested
//   with the ifldnum argument. 
//
// PROGRAM HISTORY LOG:
// 2002-10-28  Gilbert
//
// USAGE:    #include "grib2.h"
//           int g2_getfld(unsigned char *cgrib,g2int ifldnum,g2int unpack,
//                         g2int expand,gribfield **gfld)
//   INPUT ARGUMENTS:
//     cgrib    - Character pointer to the GRIB2 message
//     ifldnum  - Specifies which field in the GRIB2 message to return. 
//     unpack   - Boolean value indicating whether to unpack bitmap/data
//                1 = unpack bitmap and data values
//                0 = do not unpack bitmap and data values
//     expand   - Boolean value indicating whether the data points should be
//                expanded to the correspond grid, if a bit-map is present. 
//                1 = if possible, expand data field to grid, inserting zero
//                    values at gridpoints that are bitmapped out. 
//                    (SEE REMARKS2)
//                0 = do not expand data field, leaving it an array of
//                    consecutive data points for each "1" in the bitmap. 
//                This argument is ignored if unpack == 0 OR if the
//                returned field does not contain a bit-map. 
//
//   OUTPUT ARGUMENT:      
//     gribfield gfld; - pointer to structure gribfield containing
//                       all decoded data for the data field. 
// 
//        gfld->version = GRIB edition number ( currently 2 )
//        gfld->discipline = Message Discipline ( see Code Table 0.0 )
//        gfld->idsect = Contains the entries in the Identification
//                        Section ( Section 1 )
//                        This element is a pointer to an array
//                        that holds the data. 
//            gfld->idsect[0]  = Identification of originating Centre
//                                    ( see Common Code Table C-1 )
//                             7 - US National Weather Service
//            gfld->idsect[1]  = Identification of originating Sub-centre
//            gfld->idsect[2]  = GRIB Master Tables Version Number
//                                    ( see Code Table 1.0 )
//                             0 - Experimental
//                             1 - Initial operational version number
//            gfld->idsect[3]  = GRIB Local Tables Version Number
//                                    ( see Code Table 1.1 )
//                             0     - Local tables not used
//                             1-254 - Number of local tables version used
//            gfld->idsect[4]  = Significance of Reference Time (Code Table 1.2)
//                             0 - Analysis
//                             1 - Start of forecast
//                             2 - Verifying time of forecast
//                             3 - Observation time
//            gfld->idsect[5]  = Year ( 4 digits )
//            gfld->idsect[6]  = Month
//            gfld->idsect[7)  = Day
//            gfld->idsect[8]  = Hour
//            gfld->idsect[9]  = Minute
//            gfld->idsect[10]  = Second
//            gfld->idsect[11]  = Production status of processed data
//                                    ( see Code Table 1.3 )
//                              0 - Operational products
//                              1 - Operational test products
//                              2 - Research products
//                              3 - Re-analysis products
//            gfld->idsect[12]  = Type of processed data ( see Code Table 1.4 )
//                              0  - Analysis products
//                              1  - Forecast products
//                              2  - Analysis and forecast products
//                              3  - Control forecast products
//                              4  - Perturbed forecast products
//                              5  - Control and perturbed forecast products
//                              6  - Processed satellite observations
//                              7  - Processed radar observations
//        gfld->idsectlen = Number of elements in gfld->idsect[]. 
//        gfld->local   = Pointer to character array containing contents
//                       of Local Section 2, if included
//        gfld->locallen = length of array gfld->local[]
//        gfld->ifldnum = field number within GRIB message
//        gfld->griddef = Source of grid definition (see Code Table 3.0)
//                      0 - Specified in Code table 3.1
//                      1 - Predetermined grid Defined by originating centre
//        gfld->ngrdpts = Number of grid points in the defined grid. 
//        gfld->numoct_opt = Number of octets needed for each
//                          additional grid points definition. 
//                          Used to define number of
//                          points in each row ( or column ) for
//                          non-regular grids. 
//                          = 0, if using regular grid. 
//        gfld->interp_opt = Interpretation of list for optional points
//                          definition.   (Code Table 3.11)
//        gfld->igdtnum = Grid Definition Template Number (Code Table 3.1)
//        gfld->igdtmpl  = Contains the data values for the specified Grid
//                         Definition Template ( NN=gfld->igdtnum ).   Each
//                         element of this integer array contains an entry (in
//                         the order specified) of Grid Defintion Template 3.NN
//                         This element is a pointer to an array
//                         that holds the data. 
//        gfld->igdtlen = Number of elements in gfld->igdtmpl[].   i.e. number of
//                       entries in Grid Defintion Template 3.NN
//                       ( NN=gfld->igdtnum ). 
//        gfld->list_opt  = (Used if gfld->numoct_opt .ne.  0)  This array
//                          contains the number of grid points contained in
//                          each row ( or column ).   (part of Section 3)
//                          This element is a pointer to an array
//                          that holds the data.   This pointer is nullified
//                          if gfld->numoct_opt=0. 
//        gfld->num_opt = (Used if gfld->numoct_opt .ne.  0) 
//                        The number of entries
//                       in array ideflist.   i.e. number of rows ( or columns )
//                       for which optional grid points are defined.   This value
//                       is set to zero, if gfld->numoct_opt=0. 
//        gfdl->ipdtnum = Product Definition Template Number(see Code Table 4.0)
//        gfld->ipdtmpl  = Contains the data values for the specified Product
//                         Definition Template ( N=gfdl->ipdtnum ).  Each element
//                         of this integer array contains an entry (in the
//                         order specified) of Product Defintion Template 4.N.
//                         This element is a pointer to an array
//                         that holds the data. 
//        gfld->ipdtlen = Number of elements in gfld->ipdtmpl[].   i.e. number of
//                       entries in Product Defintion Template 4.N
//                       ( N=gfdl->ipdtnum ). 
//        gfld->coord_list  = Real array containing floating point values
//                            intended to document the vertical discretisation
//                            associated to model data on hybrid coordinate
//                            vertical levels.   (part of Section 4)
//                            This element is a pointer to an array
//                            that holds the data. 
//        gfld->num_coord = number of values in array gfld->coord_list[]. 
//        gfld->ndpts = Number of data points unpacked and returned. 
//        gfld->idrtnum = Data Representation Template Number
//                       ( see Code Table 5.0)
//        gfld->idrtmpl  = Contains the data values for the specified Data
//                         Representation Template ( N=gfld->idrtnum ).   Each
//                         element of this integer array contains an entry
//                         (in the order specified) of Product Defintion
//                         Template 5.N.
//                         This element is a pointer to an array
//                         that holds the data. 
//        gfld->idrtlen = Number of elements in gfld->idrtmpl[].   i.e. number
//                       of entries in Data Representation Template 5.N
//                       ( N=gfld->idrtnum ). 
//        gfld->unpacked = logical value indicating whether the bitmap and
//                        data values were unpacked.   If false,
//                        gfld->bmap and gfld->fld pointers are nullified. 
//        gfld->expanded = Logical value indicating whether the data field
//                         was expanded to the grid in the case where a
//                         bit-map is present.   If true, the data points in
//                         gfld->fld match the grid points and zeros were
//                         inserted at grid points where data was bit-mapped
//                         out.   If false, the data values in gfld->fld were
//                         not expanded to the grid and are just a consecutive
//                         array of data points corresponding to each value of
//                         "1" in gfld->bmap. 
//        gfld->ibmap = Bitmap indicator ( see Code Table 6.0 )
//                     0 = bitmap applies and is included in Section 6. 
//                     1-253 = Predefined bitmap applies
//                     254 = Previously defined bitmap applies to this field
//                     255 = Bit map does not apply to this product. 
//        gfld->bmap  = integer array containing decoded bitmap,
//                      if gfld->ibmap=0 or gfld->ibap=254.   Otherwise nullified
//                      This element is a pointer to an array
//                      that holds the data. 
//        gfld->fld  = Array of gfld->ndpts unpacked data points. 
//                     This element is a pointer to an array
//                     that holds the data. 
//
// 
//   RETURN VALUES:
//     ierr     - Error return code. 
//                0 = no error
//                1 = Beginning characters "GRIB" not found. 
//                2 = GRIB message is not Edition 2. 
//                3 = The data field request number was not positive. 
//                4 = End string "7777" found, but not where expected. 
//                6 = GRIB message did not contain the requested number of
//                    data fields. 
//                7 = End string "7777" not found at end of message. 
//                8 = Unrecognized Section encountered. 
//                9 = Data Representation Template 5.NN not yet implemented. 
//               15 = Error unpacking Section 1. 
//               16 = Error unpacking Section 2. 
//               10 = Error unpacking Section 3. 
//               11 = Error unpacking Section 4. 
//               12 = Error unpacking Section 5. 
//               13 = Error unpacking Section 6. 
//               14 = Error unpacking Section 7. 
//
// REMARKS: Note that struct gribfield is allocated by this routine and it
//          also contains pointers to many arrays of data that were allocated
//          during decoding.   Users are encouraged to free up this memory, 
//          when it is no longer needed, by an explicit call to routine g2_free. 
//          EXAMPLE:
//              #include "grib2.h"
//              gribfield *gfld;
//              ret=g2_getfld(cgrib,1,1,1,&gfld);
//                ...
//              g2_free(gfld);
//
//          Routine g2_info can be used to first determine
//          how many data fields exist in a given GRIB message. 
//
// REMARKS2: It may not always be possible to expand a bit-mapped data field. 
//           If a pre-defined bit-map is used and not included in the GRIB2
//           message itself, this routine would not have the necessary
//           information to expand the data.   In this case, gfld->expanded would
//           would be set to 0 (false), regardless of the value of input
//           argument expand. 
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:  
//
///////////////////////////////////////////////////////////////////////////



//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .       .     .                                        . 
// SUBPROGRAM:    g2_create 
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-10-31
//
// ABSTRACT: This routine initializes a new GRIB2 message and packs
//   GRIB2 sections 0 (Indicator Section) and 1 (Identification Section). 
//   This routine is used with routines "g2_addlocal", "g2_addgrid", 
//   "g2_addfield", and "g2_gribend" to create a complete GRIB2 message.   
//   g2_create must be called first to initialize a new GRIB2 message. 
//   Also, a call to g2_gribend is required to complete GRIB2 message
//   after all fields have been added. 
//
// PROGRAM HISTORY LOG:
// 2002-10-31  Gilbert
//
// USAGE:    int g2_create(unsigned char *cgrib,long *listsec0,long *listsec1)
//   INPUT ARGUMENTS:
//     cgrib    - Character array to contain the GRIB2 message
//     listsec0 - Contains information needed for GRIB Indicator Section 0. 
//                Must be dimensioned >= 2. 
//                listsec0[0]=Discipline-GRIB Master Table Number
//                            (see Code Table 0.0)
//                listsec0[1]=GRIB Edition Number (currently 2)
//     listsec1 - Contains information needed for GRIB Identification Section 1. 
//                Must be dimensioned >= 13. 
//                listsec1[0]=Id of orginating centre (Common Code Table C-1)
//                listsec1[1]=Id of orginating sub-centre (local table)
//                listsec1[2]=GRIB Master Tables Version Number (Code Table 1.0)
//                listsec1[3]=GRIB Local Tables Version Number (Code Table 1.1)
//                listsec1[4]=Significance of Reference Time (Code Table 1.2)
//                listsec1[5]=Reference Time - Year (4 digits)
//                listsec1[6]=Reference Time - Month
//                listsec1[7]=Reference Time - Day
//                listsec1[8]=Reference Time - Hour
//                listsec1[9]=Reference Time - Minute
//                listsec1[10]=Reference Time - Second
//                listsec1[11]=Production status of data (Code Table 1.3)
//                listsec1[12]=Type of processed data (Code Table 1.4)
//
//   OUTPUT ARGUMENTS:      
//     cgrib    - Char array to contain the new GRIB2 message. 
//                Must be allocated large enough to store the entire
//                GRIB2 message. 
//
//   RETURN VALUES:
//     ierr     - return code. 
//              > 0 = Current size of new GRIB2 message
//               -1 = Tried to use for version other than GRIB Edition 2
//
// REMARKS: This routine is intended for use with routines "g2_addlocal", 
//          "g2_addgrid", "g2_addfield", and "g2_gribend" to create a complete 
//          GRIB2 message. 
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:  
//
//$$$



//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .       .     .                                        . 
// SUBPROGRAM:    g2_addlocal 
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-11-01
//
// ABSTRACT: This routine adds a Local Use Section (Section 2) to 
//   a GRIB2 message.   It is used with routines "g2_create", 
//   "g2_addgrid", "g2_addfield",
//   and "g2_gribend" to create a complete GRIB2 message.   
//   g2_create must be called first to initialize a new GRIB2 message. 
//
// PROGRAM HISTORY LOG:
// 2002-11-01  Gilbert
//
// USAGE:    int g2_addlocal(unsigned char *cgrib,unsigned char *csec2,
//                           long lcsec2)
//   INPUT ARGUMENTS:
//     cgrib    - Char array that contains the GRIB2 message to which section
//                2 should be added. 
//     csec2    - Character array containing information to be added in
//                Section 2. 
//     lcsec2   - Number of bytes of character array csec2 to be added to
//                Section 2. 
//
//   OUTPUT ARGUMENT:      
//     cgrib    - Char array to contain the updated GRIB2 message. 
//                Must be allocated large enough to store the entire
//                GRIB2 message. 
//
//   RETURN VALUES:
//     ierr     - Return code. 
//              > 0 = Current size of updated GRIB2 message
//               -1 = GRIB message was not initialized.   Need to call
//                    routine gribcreate first. 
//               -2 = GRIB message already complete.   Cannot add new section. 
//               -3 = Sum of Section byte counts doesn't add to total byte count
//               -4 = Previous Section was not 1 or 7. 
//
// REMARKS: Note that the Local Use Section ( Section 2 ) can only follow
//          Section 1 or Section 7 in a GRIB2 message. 
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE: 
//
//$$$



//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .       .     .                                        . 
// SUBPROGRAM:    g2_addgrid 
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-11-01
//
// ABSTRACT: This routine packs up a Grid Definition Section (Section 3) 
//   and adds it to a GRIB2 message.   It is used with routines "g2_create",
//   "g2_addlocal", "g2_addfield",
//   and "g2_gribend" to create a complete GRIB2 message. 
//   g2_create must be called first to initialize a new GRIB2 message. 
//
// PROGRAM HISTORY LOG:
// 2002-11-01  Gilbert
//
// USAGE:    int g2_addgrid(unsigned char *cgrib,long *igds,g2int *igdstmpl,
//                          long *ideflist,long idefnum)
//   INPUT ARGUMENTS:
//     cgrib    - Char array that contains the GRIB2 message to which
//                section should be added. 
//     igds     - Contains information needed for GRIB Grid Definition Section 3
//                Must be dimensioned >= 5. 
//                igds[0]=Source of grid definition (see Code Table 3.0)
//                igds[1]=Number of grid points in the defined grid. 
//                igds[2]=Number of octets needed for each 
//                            additional grid points definition.   
//                            Used to define number of
//                            points in each row ( or column ) for
//                            non-regular grids.   
//                            = 0, if using regular grid. 
//                igds[3]=Interpretation of list for optional points 
//                            definition.   (Code Table 3.11)
//                igds[4]=Grid Definition Template Number (Code Table 3.1)
//     igdstmpl - Contains the data values for the specified Grid Definition
//                Template ( NN=igds[4] ).   Each element of this integer 
//                array contains an entry (in the order specified) of Grid
//                Defintion Template 3.NN
//     ideflist - (Used if igds[2] ! = 0)  This array contains the
//                number of grid points contained in each row ( or column )
//      idefnum - (Used if igds[2] ! = 0)  The number of entries
//                in array ideflist.   i.e. number of rows ( or columns )
//                for which optional grid points are defined. 
//
//   OUTPUT ARGUMENTS:      
//     cgrib    - Char array to contain the updated GRIB2 message. 
//                Must be allocated large enough to store the entire
//                GRIB2 message. 
//
//   RETURN VALUES:
//     ierr     - Return code. 
//              > 0 = Current size of updated GRIB2 message
//               -1 = GRIB message was not initialized.   Need to call
//                    routine gribcreate first. 
//               -2 = GRIB message already complete.   Cannot add new section. 
//               -3 = Sum of Section byte counts doesn't add to total byte count
//               -4 = Previous Section was not 1, 2 or 7. 
//               -5 = Could not find requested Grid Definition Template. 
//
// REMARKS: Note that the Grid Def Section ( Section 3 ) can only follow
//          Section 1, 2 or Section 7 in a GRIB2 message. 
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:  
//
//$$$



//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .       .     .                                        . 
// SUBPROGRAM:    g2_addfield 
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-11-05
//
// ABSTRACT: This routine packs up Sections 4 through 7 for a given field
//   and adds them to a GRIB2 message.   They are Product Definition Section,
//   Data Representation Section, Bit-Map Section and Data Section, 
//   respectively. 
//   This routine is used with routines "g2_create", "g2_addlocal", 
//   "g2_addgrid", and "g2_gribend" to create a complete GRIB2 message.   
//   g2_create must be called first to initialize a new GRIB2 message. 
//   Also, routine g2_addgrid must be called after g2_create and
//   before this routine to add the appropriate grid description to
//   the GRIB2 message.    Also, a call to g2_gribend is required to complete 
//   GRIB2 message after all fields have been added. 
//
// PROGRAM HISTORY LOG:
// 2002-11-05  Gilbert
//
// USAGE:    int g2_addfield(unsigned char *cgrib,g2int ipdsnum,g2int *ipdstmpl,
//              g2float *coordlist,g2int numcoord,g2int idrsnum,g2int *idrstmpl,
//              g2float *fld,g2int ngrdpts,g2int ibmap,g2int *bmap)
//   INPUT ARGUMENT LIST:
//     cgrib    - Char array that contains the GRIB2 message to which sections
//                4 through 7 should be added. 
//     ipdsnum  - Product Definition Template Number ( see Code Table 4.0)
//     ipdstmpl - Contains the data values for the specified Product Definition
//                Template ( N=ipdsnum ).   Each element of this integer 
//                array contains an entry (in the order specified) of Product
//                Defintion Template 4.N
//     coordlist- Array containg floating point values intended to document
//                the vertical discretisation associated to model data
//                on hybrid coordinate vertical levels. 
//     numcoord - number of values in array coordlist. 
//     idrsnum  - Data Representation Template Number ( see Code Table 5.0 )
//     idrstmpl - Contains the data values for the specified Data Representation
//                Template ( N=idrsnum ).   Each element of this integer 
//                array contains an entry (in the order specified) of Data
//                Representation Template 5.N
//                Note that some values in this template (eg.  reference
//                values, number of bits, etc...) may be changed by the
//                data packing algorithms. 
//                Use this to specify scaling factors and order of
//                spatial differencing, if desired. 
//     fld[]    - Array of data points to pack. 
//     ngrdpts  - Number of data points in grid. 
//                i.e.  size of fld and bmap. 
//     ibmap    - Bitmap indicator ( see Code Table 6.0 )
//                0 = bitmap applies and is included in Section 6. 
//                1-253 = Predefined bitmap applies
//                254 = Previously defined bitmap applies to this field
//                255 = Bit map does not apply to this product. 
//     bmap[]   - Integer array containing bitmap to be added. (  if ibmap=0 )
//
//   OUTPUT ARGUMENT LIST:      
//     cgrib    - Character array to contain the updated GRIB2 message. 
//                Must be allocated large enough to store the entire
//                GRIB2 message. 
//
//   RETURN VALUES:
//     ierr     - Return code. 
//              > 0 = Current size of updated GRIB2 message
//               -1 = GRIB message was not initialized.   Need to call
//                    routine gribcreate first. 
//               -2 = GRIB message already complete.   Cannot add new section. 
//               -3 = Sum of Section byte counts doesn't add to total byte count
//               -4 = Previous Section was not 3 or 7. 
//               -5 = Could not find requested Product Definition Template. 
//               -6 = Section 3 (GDS) not previously defined in message
//               -7 = Tried to use unsupported Data Representationi Template
//               -8 = Specified use of a previously defined bitmap, but one
//                    does not exist in the GRIB message. 
//
// REMARKS: Note that the Sections 4 through 7 can only follow
//          Section 3 or Section 7 in a GRIB2 message. 
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:  
//
//$$$



//$$$  SUBPROGRAM DOCUMENTATION BLOCK
//                .       .     .                                        . 
// SUBPROGRAM:    g2_gribend 
//   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2002-10-31
//
// ABSTRACT: This routine finalizes a GRIB2 message after all grids
//   and fields have been added.   It adds the End Section ( "7777" )
//   to the end of the GRIB message and calculates the length and stores
//   it in the appropriate place in Section 0. 
//   This routine is used with routines "g2_create", "g2_addlocal", 
//   "g2_addgrid", and "g2_addfield" to create a complete GRIB2 message. 
//   g2_create must be called first to initialize a new GRIB2 message. 
//
// PROGRAM HISTORY LOG:
// 2002-10-31  Gilbert
//
// USAGE:    int g2_gribend(unsigned char *cgrib)
//   INPUT ARGUMENT:
//     cgrib    - Char array containing all the data sections added
//                be previous calls to g2_create, g2_addlocal, g2_addgrid,
//                and g2_addfield. 
//
//   OUTPUT ARGUMENTS:      
//     cgrib    - Char array containing the finalized GRIB2 message
//
//   RETURN VALUES:
//     ierr     - Return code. 
//              > 0 = Length of the final GRIB2 message in bytes. 
//               -1 = GRIB message was not initialized.   Need to call
//                    routine g2_create first. 
//               -2 = GRIB message already complete.   
//               -3 = Sum of Section byte counts doesn't add to total byte count
//               -4 = Previous Section was not 7. 
//
// REMARKS: This routine is intended for use with routines "g2_create", 
//          "g2_addlocal", "g2_addgrid", and "g2_addfield" to create a complete 
//          GRIB2 message. 
//
// ATTRIBUTES:
//   LANGUAGE: C
//   MACHINE:
//
//$$$
