awips2/nativeLib/rary.cots.g2clib/g2_info.c

191 lines
6.5 KiB
C
Raw Permalink Normal View History

2017-04-21 18:33:55 -06:00
#include <stdio.h>
#include <stdlib.h>
#include "grib2.h"
g2int g2_info(unsigned char *cgrib,g2int *listsec0,g2int *listsec1,
g2int *numfields,g2int *numlocal)
//$$$ 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:
//
//$$$
{
g2int ierr,mapsec1len=13;
g2int mapsec1[13]={2,2,1,1,1,2,1,1,1,1,1,1,1};
g2int i,j,istart,iofst,lengrib,lensec0,lensec1;
g2int ipos,isecnum,nbits,lensec;
ierr=0;
*numlocal=0;
*numfields=0;
//
// Check for beginning of GRIB message in the first 100 bytes
//
istart=-1;
for (j=0;j<100;j++) {
if (cgrib[j]=='G' && cgrib[j+1]=='R' &&cgrib[j+2]=='I' &&
cgrib[j+3]=='B') {
istart=j;
break;
}
}
if (istart == -1) {
printf("g2_info: Beginning characters GRIB not found.");
ierr=1;
return(ierr);
}
//
// Unpack Section 0 - Indicator Section
//
iofst=8*(istart+6);
gbit(cgrib,listsec0+0,iofst,8); // Discipline
iofst=iofst+8;
gbit(cgrib,listsec0+1,iofst,8); // GRIB edition number
iofst=iofst+8;
iofst=iofst+32;
gbit(cgrib,&lengrib,iofst,32); // Length of GRIB message
iofst=iofst+32;
listsec0[2]=lengrib;
lensec0=16;
ipos=istart+lensec0;
//
// Currently handles only GRIB Edition 2.
//
if (listsec0[1] != 2) {
printf("g2_info: can only decode GRIB edition 2.");
ierr=2;
return(ierr);
}
//
// Unpack Section 1 - Identification Section
//
gbit(cgrib,&lensec1,iofst,32); // Length of Section 1
iofst=iofst+32;
gbit(cgrib,&isecnum,iofst,8); // Section number ( 1 )
iofst=iofst+8;
if (isecnum != 1) {
printf("g2_info: Could not find section 1.");
ierr=3;
return(ierr);
}
//
// Unpack each input value in array listsec1 into the
// the appropriate number of octets, which are specified in
// corresponding entries in array mapsec1.
//
for (i=0;i<mapsec1len;i++) {
nbits=mapsec1[i]*8;
gbit(cgrib,listsec1+i,iofst,nbits);
iofst=iofst+nbits;
}
ipos=ipos+lensec1;
//
// Loop through the remaining sections to see if they are valid.
// Also count the number of times Section 2
// and Section 4 appear.
//
for (;;) {
if (cgrib[ipos]=='7' && cgrib[ipos+1]=='7' && cgrib[ipos+2]=='7' &&
cgrib[ipos+3]=='7') {
ipos=ipos+4;
if (ipos != (istart+lengrib)) {
printf("g2_info: '7777' found, but not where expected.\n");
ierr=4;
return(ierr);
}
break;
}
iofst=ipos*8;
gbit(cgrib,&lensec,iofst,32); // Get Length of Section
iofst=iofst+32;
gbit(cgrib,&isecnum,iofst,8); // Get Section number
iofst=iofst+8;
ipos=ipos+lensec; // Update beginning of section pointer
if (ipos > (istart+lengrib)) {
printf("g2_info: '7777' not found at end of GRIB message.\n");
ierr=5;
return(ierr);
}
if ( isecnum>=2 && isecnum<=7 ) {
if (isecnum == 2) // Local Section 2
// increment counter for total number of local sections found
(*numlocal)++;
else if (isecnum == 4)
// increment counter for total number of fields found
(*numfields)++;
}
else {
printf("g2_info: Invalid section number found in GRIB message: %ld\n" ,isecnum);
ierr=6;
return(ierr);
}
}
return(0);
}