Projects
home:Eustace:branches:Eulaceura:Factory
g2clib
_service:obs_scm:g2clib-1672715060.88a25f7.obscpio
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:g2clib-1672715060.88a25f7.obscpio of Package g2clib
07070100000000000081A400000000000000000000000163B39B34000003C4000000000000000000000000000000000000002700000000g2clib-1672715060.88a25f7/README.en.md# g2clib Reason why the repository's state is set to be closed: https://gitee.com/openeuler/community/pulls/3323 #### Description GRIB2 encoder/decoder and search/indexing routines in C #### Software Architecture Software architecture description #### Installation 1. xxxx 2. xxxx 3. xxxx #### Instructions 1. xxxx 2. xxxx 3. xxxx #### Contribution 1. Fork the repository 2. Create Feat_xxx branch 3. Commit your code 4. Create Pull Request #### Gitee Feature 1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md 2. Gitee blog [blog.gitee.com](https://blog.gitee.com) 3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) 4. The most valuable open source project [GVP](https://gitee.com/gvp) 5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) 6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) 07070100000001000081A400000000000000000000000163B39B3400000059000000000000000000000000000000000000002400000000g2clib-1672715060.88a25f7/README.md 仓库状态设置为关闭的原因: https://gitee.com/openeuler/community/pulls/3323 07070100000002000081A400000000000000000000000163B39B3400070800000000000000000000000000000000000000002B00000000g2clib-1672715060.88a25f7/g2clib-1.6.0.targ2clib-1.6.0/0002755002373300042670000000000012650424116012526 5ustar Boi.Vuongglobalg2clib-1.6.0/CHANGES0000644002373300042670000001000112650423335013511 0ustar Boi.Vuongglobalglib-1.0 - August 2003 - Original version g2libc-1.0.1 - May 2004 - Changed the library name from "libg2c.a" to "libgrib2c.a" to avoid conflict with the g77 libg2c library. - Added support for Grid Definition Template 3.31, Albers Equal Area. - Changed most PDT templates in module pdstemplates to allow negative surface values. - Many minor changes to help get clean compiles. g2libc-1.0.2 - December 2004 - WMO approved the JPEG2000 and PNG Data Representation Templates ( 5.40000 and 5.40010, respectively ) for operational use. The templates were assigned WMO values of 5.40 and 5.41, respectively. Changes were made to the source to recognize either template number. - Fixed bug encountered when packing a near constant field with DRT 5.40 or 5.40000 (JPEG2000). - Added consistency check, provided by Arthur Taylor/MDL, used when unpacking Data Templates 7.2 and 7.3. - Added functionality to support encoding of "Missing" data values within the data field when using Data Representation Templates 5.2 (complex packing) and 5.3 (complex packing and spatial differencing). See octets 23 - 31 in DRTs 5.2 and 5.3 for more info on missing value management. - Increased the packing efficiency of Data Representation Templates 5.2 and 5.3 by adding MDL/Glahn algorithm for determining effective groupings. g2libc-1.0.3 - December 2005 - Two bug fixes: 1) Error encoding constant data field. 2) Error encoding grid with large bitmap using DRT 5.40 - JPEG2000. g2libc-1.0.5 - August 2007 - Added GDT 3.204 Curvilinear Orthogonal Grid g2libc-1.1.7 - August 2008 - Added GDT 3.32768 Rot Lat/Lon E-grid (Arakawa) g2libc-1.1.8 - January 2009 - Initialize variable lencsec2 in routine g2_unpack2.c variable ndpts in routine g2_unpack7.c - Changed the structure name template to gtemplate to avoid of reserved word in C++ - Change routine seekgb.c to use 4 bytes instead of sizeof(g2int) g2libc-1.1.9 - June 2009 - Updated version jasper-1.900.1, libpng-1.2.35 and zlib-1.2.3 - Fixed bug causing seg fault when using PNG 1.2.35 g2libc-1.2.0 - March 2010 - Added PDT 4.31 Satellite Product - Added PDT 4.15 WAFS Product g2libc-1.2.1 - August 2010 - Added PDT 4.40,4.41,4.42,4.43 for Atmospheric Chemical Constituents - Added GDT 3.32769 Rot Lat/Lon None E-grid (Arakawa) - If section 2 has zero length, return IERR=0 g2libc-1.2.2 - March 2011 - Corrected PDT 4.42,4.43 for Atmospheric Chemical Constituents g2libc-1.2.3 - November 2011 - Fixed bugs in routines dec_png.c and enc_png.c g2libc-1.4.0 - May 2012 - Added PDT 4.44,4.45,4.46,4.47,4.48 for Aerosol products - PDT 4.50,4.51,4.52 iand 4.91 for Categorical forecast at a horizonal g2libc-1.5.0 - Sept. 2013 - Added PDT 4.33,4.34,4.53,4.54,4.50 - Added GDT 3.4,3.5,3.12,3.101,3.140 - Free up memory igds g2libc-1.6.0 - October 2015 - Added PDT 4.57, 4.60, 4.61 and - Allow a forecast time to be negative g2clib-1.6.0/README0000644002373300042670000000540512522400360013401 0ustar Boi.Vuongglobal August 06, 2013 W/SIB:VUONG g2clib Library. This library contains "C" decoder/encoder routines for GRIB edition 2. The user API for the GRIB2 routines is described in file "grib2c.doc". This "C" source code conatins many uses of the C++ comment style "//". Please make sure you include the appropriate compiler option in the CFLAGS variable in the makefile to allow the use of "//" comment indicators. We have added support for PNG and JPEG2000 image compression algorithms within the GRIB2 standard. If you would like to compile this library to utilize these GRIB2 Templates, make sure that -DUSE_PNG and -DUSE_JPEG2000 are specified in the DEFS variable in the makefile. You will also need to download and install the external libraries listed below, if they are not already installed on your system. If you do not wish to bother with the external libs and don't need PNG and JPEG2000 support, you can remove the -DUSE_PNG and -DUSE_JPEG2000 flags from the DEFS variable in the makefile. ------------------------------------------------------------------------------- External Libraries: libjasper.a - This library is a C implementation of the JPEG-2000 Part-1 standard (i.e., ISO/IEC 15444-1). This library is required if JPEG2000 support in GRIB2 is desired. If not, remove the -DUSE_JPEG2000 option from the DEFS variable in the makefile. Download version jasper-1.900.1 from the JasPer Project's home page, http://www.ece.uvic.ca/~mdadams/jasper/. More information about JPEG2000 can be found at http://www.jpeg.org/JPEG2000.html. libpng.a This library is a C implementation of the Portable Network Graphics PNG image compression format. This library is required if PNG support in GRIB2 is desired. If not, remove the -DUSE_PNG option from the DEFS variable in the makefile. If not already installed on your system, download version libpng-1.2.44 from http://www.libpng.org/pub/png/libpng.html. More information about PNG can be found at http://www.libpng.org/pub/png/. libz.a This library contains compression/decompression routines used by libpng.a for PNG image compression support. This library is required if PNG support in GRIB2 is desired. If not, remove the -DUSE_PNG option from the DEFS variable in g2lib/makefile. If not already installed on your system, download version zlib-1.2.6 from http://www.gzip.org/zlib/. g2clib-1.6.0/cmplxpack.c0000755002373300042670000000517212522400360014653 0ustar Boi.Vuongglobal#include "grib2.h" void cmplxpack(g2float *fld,g2int ndpts, g2int idrsnum,g2int *idrstmpl, unsigned char *cpack, g2int *lcpack) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: cmplxpack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2004-08-27 // // ABSTRACT: This subroutine packs up a data field using a complex // packing algorithm as defined in the GRIB2 documention. It // supports GRIB2 complex packing templates with or without // spatial differences (i.e. DRTs 5.2 and 5.3). // It also fills in GRIB2 Data Representation Template 5.2 or 5.3 // with the appropriate values. // // PROGRAM HISTORY LOG: // 2004-08-27 Gilbert // // USAGE: cmplxpack(g2float *fld,g2int ndpts, g2int idrsnum,g2int *idrstmpl, // unsigned char *cpack, g2int *lcpack) // INPUT ARGUMENT LIST: // fld[] - Contains the data values to pack // ndpts - The number of data values in array fld[] // idrsnum - Data Representation Template number 5.N // Must equal 2 or 3. // idrstmpl - Contains the array of values for Data Representation // Template 5.2 or 5.3 // [0] = Reference value - ignored on input // [1] = Binary Scale Factor // [2] = Decimal Scale Factor // . // . // [6] = Missing value management // [7] = Primary missing value // [8] = Secondary missing value // . // . // [16] = Order of Spatial Differencing ( 1 or 2 ) // . // . // // OUTPUT ARGUMENT LIST: // idrstmpl - Contains the array of values for Data Representation // Template 5.3 // [0] = Reference value - set by compack routine. // [1] = Binary Scale Factor - unchanged from input // [2] = Decimal Scale Factor - unchanged from input // . // . // cpack - The packed data field (character*1 array) // lcpack - length of packed field cpack[]. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { if ( idrstmpl[6] == 0 ) { // No internal missing values compack(fld,ndpts,idrsnum,idrstmpl,cpack,lcpack); } else if ( idrstmpl[6] == 1 || idrstmpl[6] == 2) { misspack(fld,ndpts,idrsnum,idrstmpl,cpack,lcpack); } else { printf("cmplxpack: Don:t recognize Missing value option."); *lcpack=-1; } } g2clib-1.6.0/compack.c0000755002373300042670000003477212522400360014316 0ustar Boi.Vuongglobal#include <stdlib.h> #include <math.h> #include "grib2.h" void compack(g2float *fld,g2int ndpts,g2int idrsnum,g2int *idrstmpl, unsigned char *cpack,g2int *lcpack) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: compack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-11-07 // // ABSTRACT: This subroutine packs up a data field using a complex // packing algorithm as defined in the GRIB2 documention. It // supports GRIB2 complex packing templates with or without // spatial differences (i.e. DRTs 5.2 and 5.3). // It also fills in GRIB2 Data Representation Template 5.2 or 5.3 // with the appropriate values. // // PROGRAM HISTORY LOG: // 2002-11-07 Gilbert // // USAGE: void compack(g2float *fld,g2int ndpts,g2int idrsnum, // g2int *idrstmpl,unsigned char *cpack,g2int *lcpack) // // INPUT ARGUMENTS: // fld[] - Contains the data values to pack // ndpts - The number of data values in array fld[] // idrsnum - Data Representation Template number 5.N // Must equal 2 or 3. // idrstmpl - Contains the array of values for Data Representation // Template 5.2 or 5.3 // [0] = Reference value - ignored on input // [1] = Binary Scale Factor // [2] = Decimal Scale Factor // . // . // [6] = Missing value management // [7] = Primary missing value // [8] = Secondary missing value // . // . // [16] = Order of Spatial Differencing ( 1 or 2 ) // . // . // // OUTPUT ARGUMENTS: // idrstmpl - Contains the array of values for Data Representation // Template 5.3 // [0] = Reference value - set by compack routine. // [1] = Binary Scale Factor - unchanged from input // [2] = Decimal Scale Factor - unchanged from input // . // . // cpack - The packed data field // lcpack - length of packed field cpack. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$ { static g2int zero=0; g2int *ifld,*gref,*glen,*gwidth; g2int *jmin, *jmax, *lbit; g2int i,j,n,nbits,imin,imax,left; g2int isd,itemp,ilmax,ngwidthref=0,nbitsgwidth=0; g2int nglenref=0,nglenlast=0,iofst,ival1,ival2; g2int minsd,nbitsd=0,maxorig,nbitorig,ngroups; g2int lg,ng,igmax,iwmax,nbitsgref; g2int glength,grpwidth,nbitsglen=0; g2int kfildo, minpk, inc, maxgrps, ibit, jbit, kbit, novref, lbitref; g2int missopt, miss1, miss2, ier; g2float bscale,dscale,rmax,rmin,temp; static g2int simple_alg = 0; static g2float alog2=0.69314718; // ln(2.0) static g2int one=1; bscale=int_power(2.0,-idrstmpl[1]); dscale=int_power(10.0,idrstmpl[2]); // // Find max and min values in the data // rmax=fld[0]; rmin=fld[0]; for (j=1;j<ndpts;j++) { if (fld[j] > rmax) rmax=fld[j]; if (fld[j] < rmin) rmin=fld[j]; } // // If max and min values are not equal, pack up field. // If they are equal, we have a constant field, and the reference // value (rmin) is the value for each point in the field and // set nbits to 0. // if (rmin != rmax) { iofst=0; ifld=calloc(ndpts,sizeof(g2int)); gref=calloc(ndpts,sizeof(g2int)); gwidth=calloc(ndpts,sizeof(g2int)); glen=calloc(ndpts,sizeof(g2int)); // // Scale original data // if (idrstmpl[1] == 0) { // No binary scaling imin=(g2int)rint(rmin*dscale); //imax=(g2int)rint(rmax*dscale); rmin=(g2float)imin; for (j=0;j<ndpts;j++) ifld[j]=(g2int)rint(fld[j]*dscale)-imin; } else { // Use binary scaling factor rmin=rmin*dscale; //rmax=rmax*dscale; for (j=0;j<ndpts;j++) ifld[j]=(g2int)rint(((fld[j]*dscale)-rmin)*bscale); } // // Calculate Spatial differences, if using DRS Template 5.3 // if (idrsnum == 3) { // spatial differences if (idrstmpl[16]!=1 && idrstmpl[16]!=2) idrstmpl[16]=1; if (idrstmpl[16] == 1) { // first order ival1=ifld[0]; for (j=ndpts-1;j>0;j--) ifld[j]=ifld[j]-ifld[j-1]; ifld[0]=0; } else if (idrstmpl[16] == 2) { // second order ival1=ifld[0]; ival2=ifld[1]; for (j=ndpts-1;j>1;j--) ifld[j]=ifld[j]-(2*ifld[j-1])+ifld[j-2]; ifld[0]=0; ifld[1]=0; } // // subtract min value from spatial diff field // isd=idrstmpl[16]; minsd=ifld[isd]; for (j=isd;j<ndpts;j++) if ( ifld[j] < minsd ) minsd=ifld[j]; for (j=isd;j<ndpts;j++) ifld[j]=ifld[j]-minsd; // // find num of bits need to store minsd and add 1 extra bit // to indicate sign // temp=log((double)(abs(minsd)+1))/alog2; nbitsd=(g2int)ceil(temp)+1; // // find num of bits need to store ifld[0] ( and ifld[1] // if using 2nd order differencing ) // maxorig=ival1; if (idrstmpl[16]==2 && ival2>ival1) maxorig=ival2; temp=log((double)(maxorig+1))/alog2; nbitorig=(g2int)ceil(temp)+1; if (nbitorig > nbitsd) nbitsd=nbitorig; // increase number of bits to even multiple of 8 ( octet ) if ( (nbitsd%8) != 0) nbitsd=nbitsd+(8-(nbitsd%8)); // // Store extra spatial differencing info into the packed // data section. // if (nbitsd != 0) { // pack first original value if (ival1 >= 0) { sbit(cpack,&ival1,iofst,nbitsd); iofst=iofst+nbitsd; } else { sbit(cpack,&one,iofst,1); iofst=iofst+1; itemp=abs(ival1); sbit(cpack,&itemp,iofst,nbitsd-1); iofst=iofst+nbitsd-1; } if (idrstmpl[16] == 2) { // pack second original value if (ival2 >= 0) { sbit(cpack,&ival2,iofst,nbitsd); iofst=iofst+nbitsd; } else { sbit(cpack,&one,iofst,1); iofst=iofst+1; itemp=abs(ival2); sbit(cpack,&itemp,iofst,nbitsd-1); iofst=iofst+nbitsd-1; } } // pack overall min of spatial differences if (minsd >= 0) { sbit(cpack,&minsd,iofst,nbitsd); iofst=iofst+nbitsd; } else { sbit(cpack,&one,iofst,1); iofst=iofst+1; itemp=abs(minsd); sbit(cpack,&itemp,iofst,nbitsd-1); iofst=iofst+nbitsd-1; } } //printf("SDp %ld %ld %ld %ld\n",ival1,ival2,minsd,nbitsd); } // end of spatial diff section // // Determine Groups to be used. // if ( simple_alg == 1 ) { // set group length to 10; calculate number of groups // and length of last group ngroups=ndpts/10; for (j=0;j<ngroups;j++) glen[j]=10; itemp=ndpts%10; if (itemp != 0) { ngroups=ngroups+1; glen[ngroups-1]=itemp; } } else { // Use Dr. Glahn's algorithm for determining grouping. // kfildo=6; minpk=10; inc=1; maxgrps=(ndpts/minpk)+1; jmin = calloc(maxgrps,sizeof(g2int)); jmax = calloc(maxgrps,sizeof(g2int)); lbit = calloc(maxgrps,sizeof(g2int)); missopt=0; pack_gp(&kfildo,ifld,&ndpts,&missopt,&minpk,&inc,&miss1,&miss2, jmin,jmax,lbit,glen,&maxgrps,&ngroups,&ibit,&jbit, &kbit,&novref,&lbitref,&ier); //print *,'SAGier = ',ier,ibit,jbit,kbit,novref,lbitref for ( ng=0; ng<ngroups; ng++) glen[ng]=glen[ng]+novref; free(jmin); free(jmax); free(lbit); } // // For each group, find the group's reference value // and the number of bits needed to hold the remaining values // n=0; for (ng=0;ng<ngroups;ng++) { // find max and min values of group gref[ng]=ifld[n]; imax=ifld[n]; j=n+1; for (lg=1;lg<glen[ng];lg++) { if (ifld[j] < gref[ng]) gref[ng]=ifld[j]; if (ifld[j] > imax) imax=ifld[j]; j++; } // calc num of bits needed to hold data if ( gref[ng] != imax ) { temp=log((double)(imax-gref[ng]+1))/alog2; gwidth[ng]=(g2int)ceil(temp); } else gwidth[ng]=0; // Subtract min from data j=n; for (lg=0;lg<glen[ng];lg++) { ifld[j]=ifld[j]-gref[ng]; j++; } // increment fld array counter n=n+glen[ng]; } // // Find max of the group references and calc num of bits needed // to pack each groups reference value, then // pack up group reference values // igmax=gref[0]; for (j=1;j<ngroups;j++) if (gref[j] > igmax) igmax=gref[j]; if (igmax != 0) { temp=log((double)(igmax+1))/alog2; nbitsgref=(g2int)ceil(temp); sbits(cpack,gref,iofst,nbitsgref,0,ngroups); itemp=nbitsgref*ngroups; iofst=iofst+itemp; // Pad last octet with Zeros, if necessary, if ( (itemp%8) != 0) { left=8-(itemp%8); sbit(cpack,&zero,iofst,left); iofst=iofst+left; } } else nbitsgref=0; // // Find max/min of the group widths and calc num of bits needed // to pack each groups width value, then // pack up group width values // iwmax=gwidth[0]; ngwidthref=gwidth[0]; for (j=1;j<ngroups;j++) { if (gwidth[j] > iwmax) iwmax=gwidth[j]; if (gwidth[j] < ngwidthref) ngwidthref=gwidth[j]; } if (iwmax != ngwidthref) { temp=log((double)(iwmax-ngwidthref+1))/alog2; nbitsgwidth=(g2int)ceil(temp); for (i=0;i<ngroups;i++) gwidth[i]=gwidth[i]-ngwidthref; sbits(cpack,gwidth,iofst,nbitsgwidth,0,ngroups); itemp=nbitsgwidth*ngroups; iofst=iofst+itemp; // Pad last octet with Zeros, if necessary, if ( (itemp%8) != 0) { left=8-(itemp%8); sbit(cpack,&zero,iofst,left); iofst=iofst+left; } } else { nbitsgwidth=0; for (i=0;i<ngroups;i++) gwidth[i]=0; } // // Find max/min of the group lengths and calc num of bits needed // to pack each groups length value, then // pack up group length values // //write(77,*)'GLENS: ',(glen(j),j=1,ngroups) ilmax=glen[0]; nglenref=glen[0]; for (j=1;j<ngroups-1;j++) { if (glen[j] > ilmax) ilmax=glen[j]; if (glen[j] < nglenref) nglenref=glen[j]; } nglenlast=glen[ngroups-1]; if (ilmax != nglenref) { temp=log((double)(ilmax-nglenref+1))/alog2; nbitsglen=(g2int)ceil(temp); for (i=0;i<ngroups-1;i++) glen[i]=glen[i]-nglenref; sbits(cpack,glen,iofst,nbitsglen,0,ngroups); itemp=nbitsglen*ngroups; iofst=iofst+itemp; // Pad last octet with Zeros, if necessary, if ( (itemp%8) != 0) { left=8-(itemp%8); sbit(cpack,&zero,iofst,left); iofst=iofst+left; } } else { nbitsglen=0; for (i=0;i<ngroups;i++) glen[i]=0; } // // For each group, pack data values // n=0; for (ng=0;ng<ngroups;ng++) { glength=glen[ng]+nglenref; if (ng == (ngroups-1) ) glength=nglenlast; grpwidth=gwidth[ng]+ngwidthref; if ( grpwidth != 0 ) { sbits(cpack,ifld+n,iofst,grpwidth,0,glength); iofst=iofst+(grpwidth*glength); } n=n+glength; } // Pad last octet with Zeros, if necessary, if ( (iofst%8) != 0) { left=8-(iofst%8); sbit(cpack,&zero,iofst,left); iofst=iofst+left; } *lcpack=iofst/8; // if ( ifld!=0 ) free(ifld); if ( gref!=0 ) free(gref); if ( gwidth!=0 ) free(gwidth); if ( glen!=0 ) free(glen); } else { // Constant field ( max = min ) nbits=0; *lcpack=0; nbitsgref=0; ngroups=0; } // // Fill in ref value and number of bits in Template 5.2 // mkieee(&rmin,idrstmpl+0,1); // ensure reference value is IEEE format idrstmpl[3]=nbitsgref; idrstmpl[4]=0; // original data were reals idrstmpl[5]=1; // general group splitting idrstmpl[6]=0; // No internal missing values idrstmpl[7]=0; // Primary missing value idrstmpl[8]=0; // secondary missing value idrstmpl[9]=ngroups; // Number of groups idrstmpl[10]=ngwidthref; // reference for group widths idrstmpl[11]=nbitsgwidth; // num bits used for group widths idrstmpl[12]=nglenref; // Reference for group lengths idrstmpl[13]=1; // length increment for group lengths idrstmpl[14]=nglenlast; // True length of last group idrstmpl[15]=nbitsglen; // num bits used for group lengths if (idrsnum == 3) { idrstmpl[17]=nbitsd/8; // num bits used for extra spatial // differencing values } } g2clib-1.6.0/comunpack.c0000755002373300042670000002523512522400360014653 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" int comunpack(unsigned char *cpack,g2int lensec,g2int idrsnum,g2int *idrstmpl,g2int ndpts,g2float *fld) ////$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: comunpack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-29 // // ABSTRACT: This subroutine unpacks a data field that was packed using a // complex packing algorithm as defined in the GRIB2 documention, // using info from the GRIB2 Data Representation Template 5.2 or 5.3. // Supports GRIB2 complex packing templates with or without // spatial differences (i.e. DRTs 5.2 and 5.3). // // PROGRAM HISTORY LOG: // 2002-10-29 Gilbert // 2004-12-16 Gilbert - Added test ( provided by Arthur Taylor/MDL ) // to verify that group widths and lengths are // consistent with section length. // // USAGE: int comunpack(unsigned char *cpack,g2int lensec,g2int idrsnum, // g2int *idrstmpl, g2int ndpts,g2float *fld) // INPUT ARGUMENT LIST: // cpack - pointer to the packed data field. // lensec - length of section 7 (used for error checking). // idrsnum - Data Representation Template number 5.N // Must equal 2 or 3. // idrstmpl - pointer to the array of values for Data Representation // Template 5.2 or 5.3 // ndpts - The number of data values to unpack // // OUTPUT ARGUMENT LIST: // fld - Contains the unpacked data values. fld must be allocated // with at least ndpts*sizeof(g2float) bytes before // calling this routine. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$// { g2int nbitsd=0,isign; g2int j,iofst,ival1,ival2,minsd,itemp,l,k,n,non=0; g2int *ifld,*ifldmiss=0; g2int *gref,*gwidth,*glen; g2int itype,ngroups,nbitsgref,nbitsgwidth,nbitsglen; g2int msng1,msng2; g2float ref,bscale,dscale,rmiss1,rmiss2; g2int totBit, totLen; //printf('IDRSTMPL: ',(idrstmpl(j),j=1,16) rdieee(idrstmpl+0,&ref,1); // printf("SAGTref: %f\n",ref); bscale = (g2float)int_power(2.0,idrstmpl[1]); dscale = (g2float)int_power(10.0,-idrstmpl[2]); nbitsgref = idrstmpl[3]; itype = idrstmpl[4]; ngroups = idrstmpl[9]; nbitsgwidth = idrstmpl[11]; nbitsglen = idrstmpl[15]; if (idrsnum == 3) nbitsd=idrstmpl[17]*8; // Constant field if (ngroups == 0) { for (j=0;j<ndpts;j++) fld[j]=ref; return(0); } iofst=0; ifld=(g2int *)calloc(ndpts,sizeof(g2int)); //printf("ALLOC ifld: %d %x\n",(int)ndpts,ifld); gref=(g2int *)calloc(ngroups,sizeof(g2int)); //printf("ALLOC gref: %d %x\n",(int)ngroups,gref); gwidth=(g2int *)calloc(ngroups,sizeof(g2int)); //printf("ALLOC gwidth: %d %x\n",(int)ngroups,gwidth); // // Get missing values, if supplied // if ( idrstmpl[6] == 1 ) { if (itype == 0) rdieee(idrstmpl+7,&rmiss1,1); else rmiss1=(g2float)idrstmpl[7]; } if ( idrstmpl[6] == 2 ) { if (itype == 0) { rdieee(idrstmpl+7,&rmiss1,1); rdieee(idrstmpl+8,&rmiss2,1); } else { rmiss1=(g2float)idrstmpl[7]; rmiss2=(g2float)idrstmpl[8]; } } //printf("RMISSs: %f %f %f \n",rmiss1,rmiss2,ref); // // Extract Spatial differencing values, if using DRS Template 5.3 // if (idrsnum == 3) { if (nbitsd != 0) { // wne mistake here shoujld be unsigned int gbit(cpack,&ival1,iofst,nbitsd); iofst=iofst+nbitsd; // gbit(cpack,&isign,iofst,1); // iofst=iofst+1; // gbit(cpack,&ival1,iofst,nbitsd-1); // iofst=iofst+nbitsd-1; // if (isign == 1) ival1=-ival1; if (idrstmpl[16] == 2) { // wne mistake here shoujld be unsigned int gbit(cpack,&ival2,iofst,nbitsd); iofst=iofst+nbitsd; // gbit(cpack,&isign,iofst,1); // iofst=iofst+1; // gbit(cpack,&ival2,iofst,nbitsd-1); // iofst=iofst+nbitsd-1; // if (isign == 1) ival2=-ival2; } gbit(cpack,&isign,iofst,1); iofst=iofst+1; gbit(cpack,&minsd,iofst,nbitsd-1); iofst=iofst+nbitsd-1; if (isign == 1) minsd=-minsd; } else { ival1=0; ival2=0; minsd=0; } //printf("SDu %ld %ld %ld %ld \n",ival1,ival2,minsd,nbitsd); } // // Extract Each Group's reference value // //printf("SAG1: %ld %ld %ld \n",nbitsgref,ngroups,iofst); if (nbitsgref != 0) { gbits(cpack,gref+0,iofst,nbitsgref,0,ngroups); itemp=nbitsgref*ngroups; iofst=iofst+itemp; if (itemp%8 != 0) iofst=iofst+(8-(itemp%8)); } else { for (j=0;j<ngroups;j++) gref[j]=0; } // // Extract Each Group's bit width // //printf("SAG2: %ld %ld %ld %ld \n",nbitsgwidth,ngroups,iofst,idrstmpl[10]); if (nbitsgwidth != 0) { gbits(cpack,gwidth+0,iofst,nbitsgwidth,0,ngroups); itemp=nbitsgwidth*ngroups; iofst=iofst+itemp; if (itemp%8 != 0) iofst=iofst+(8-(itemp%8)); } else { for (j=0;j<ngroups;j++) gwidth[j]=0; } for (j=0;j<ngroups;j++) gwidth[j]=gwidth[j]+idrstmpl[10]; // // Extract Each Group's length (number of values in each group) // glen=(g2int *)calloc(ngroups,sizeof(g2int)); //printf("ALLOC glen: %d %x\n",(int)ngroups,glen); //printf("SAG3: %ld %ld %ld %ld %ld \n",nbitsglen,ngroups,iofst,idrstmpl[13],idrstmpl[12]); if (nbitsglen != 0) { gbits(cpack,glen,iofst,nbitsglen,0,ngroups); itemp=nbitsglen*ngroups; iofst=iofst+itemp; if (itemp%8 != 0) iofst=iofst+(8-(itemp%8)); } else { for (j=0;j<ngroups;j++) glen[j]=0; } for (j=0;j<ngroups;j++) glen[j]=(glen[j]*idrstmpl[13])+idrstmpl[12]; glen[ngroups-1]=idrstmpl[14]; // // Test to see if the group widths and lengths are consistent with number of // values, and length of section 7. // totBit = 0; totLen = 0; for (j=0;j<ngroups;j++) { totBit += (gwidth[j]*glen[j]); totLen += glen[j]; } if (totLen != ndpts) { return 1; } if (totBit / 8. > lensec) { return 1; } // // For each group, unpack data values // if ( idrstmpl[6] == 0 ) { // no missing values n=0; for (j=0;j<ngroups;j++) { if (gwidth[j] != 0) { gbits(cpack,ifld+n,iofst,gwidth[j],0,glen[j]); for (k=0;k<glen[j];k++) { ifld[n]=ifld[n]+gref[j]; n=n+1; } } else { for (l=n;l<n+glen[j];l++) ifld[l]=gref[j]; n=n+glen[j]; } iofst=iofst+(gwidth[j]*glen[j]); } } else if ( idrstmpl[6]==1 || idrstmpl[6]==2 ) { // missing values included ifldmiss=(g2int *)malloc(ndpts*sizeof(g2int)); //printf("ALLOC ifldmiss: %d %x\n",(int)ndpts,ifldmiss); for (j=0;j<ndpts;j++) ifldmiss[j]=0; n=0; non=0; for (j=0;j<ngroups;j++) { //printf(" SAGNGP %d %d %d %d\n",j,gwidth[j],glen[j],gref[j]); if (gwidth[j] != 0) { msng1=(g2int)int_power(2.0,gwidth[j])-1; msng2=msng1-1; gbits(cpack,ifld+n,iofst,gwidth[j],0,glen[j]); iofst=iofst+(gwidth[j]*glen[j]); for (k=0;k<glen[j];k++) { if (ifld[n] == msng1) { ifldmiss[n]=1; //ifld[n]=0; } else if (idrstmpl[6]==2 && ifld[n]==msng2) { ifldmiss[n]=2; //ifld[n]=0; } else { ifldmiss[n]=0; ifld[non++]=ifld[n]+gref[j]; } n++; } } else { msng1=(g2int)int_power(2.0,nbitsgref)-1; msng2=msng1-1; if (gref[j] == msng1) { for (l=n;l<n+glen[j];l++) ifldmiss[l]=1; } else if (idrstmpl[6]==2 && gref[j]==msng2) { for (l=n;l<n+glen[j];l++) ifldmiss[l]=2; } else { for (l=n;l<n+glen[j];l++) ifldmiss[l]=0; for (l=non;l<non+glen[j];l++) ifld[l]=gref[j]; non += glen[j]; } n=n+glen[j]; } } } if ( gref != 0 ) free(gref); if ( gwidth != 0 ) free(gwidth); if ( glen != 0 ) free(glen); // // If using spatial differences, add overall min value, and // sum up recursively // //printf("SAGod: %ld %ld\n",idrsnum,idrstmpl[16]); if (idrsnum == 3) { // spatial differencing if (idrstmpl[16] == 1) { // first order ifld[0]=ival1; if ( idrstmpl[6] == 0 ) itemp=ndpts; // no missing values else itemp=non; for (n=1;n<itemp;n++) { ifld[n]=ifld[n]+minsd; ifld[n]=ifld[n]+ifld[n-1]; } } else if (idrstmpl[16] == 2) { // second order ifld[0]=ival1; ifld[1]=ival2; if ( idrstmpl[6] == 0 ) itemp=ndpts; // no missing values else itemp=non; for (n=2;n<itemp;n++) { ifld[n]=ifld[n]+minsd; ifld[n]=ifld[n]+(2*ifld[n-1])-ifld[n-2]; } } } // // Scale data back to original form // //printf("SAGT: %f %f %f\n",ref,bscale,dscale); if ( idrstmpl[6] == 0 ) { // no missing values for (n=0;n<ndpts;n++) { fld[n]=(((g2float)ifld[n]*bscale)+ref)*dscale; } } else if ( idrstmpl[6]==1 || idrstmpl[6]==2 ) { // missing values included non=0; for (n=0;n<ndpts;n++) { if ( ifldmiss[n] == 0 ) { fld[n]=(((g2float)ifld[non++]*bscale)+ref)*dscale; //printf(" SAG %d %f %d %f %f %f\n",n,fld[n],ifld[non-1],bscale,ref,dscale); } else if ( ifldmiss[n] == 1 ) fld[n]=rmiss1; else if ( ifldmiss[n] == 2 ) fld[n]=rmiss2; } if ( ifldmiss != 0 ) free(ifldmiss); } if ( ifld != 0 ) free(ifld); return(0); } g2clib-1.6.0/dec_jpeg2000.c0000644002373300042670000000745712522400360014740 0ustar Boi.Vuongglobal#ifndef USE_JPEG2000 void dummy(void) {} #else /* USE_JPEG2000 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "grib2.h" #include "jasper/jasper.h" #define JAS_1_700_2 int dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: dec_jpeg2000 Decodes JPEG2000 code stream * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02 * * ABSTRACT: This Function decodes a JPEG2000 code stream specified in the * JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) using JasPer * Software version 1.500.4 (or 1.700.2) written by the University of British * Columbia and Image Power Inc, and others. * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. * * PROGRAM HISTORY LOG: * 2002-12-02 Gilbert * * USAGE: int dec_jpeg2000(char *injpc,g2int bufsize,g2int *outfld) * * INPUT ARGUMENTS: * injpc - Input JPEG2000 code stream. * bufsize - Length (in bytes) of the input JPEG2000 code stream. * * OUTPUT ARGUMENTS: * outfld - Output matrix of grayscale image values. * * RETURN VALUES : * 0 = Successful decode * -3 = Error decode jpeg2000 code stream. * -5 = decoded image had multiple color components. * Only grayscale is expected. * * REMARKS: * * Requires JasPer Software version 1.500.4 or 1.700.2 * * ATTRIBUTES: * LANGUAGE: C * MACHINE: IBM SP * *$$$*/ { int ier; g2int i,j,k; jas_image_t *image=0; jas_stream_t *jpcstream; jas_image_cmpt_t *pcmpt; char *opts=0; jas_matrix_t *data; // jas_init(); ier=0; // // Create jas_stream_t containing input JPEG200 codestream in memory. // jpcstream=jas_stream_memopen(injpc,bufsize); // // Decode JPEG200 codestream into jas_image_t structure. // image=jpc_decode(jpcstream,opts); if ( image == 0 ) { printf(" jpc_decode return\n"); return -3; } pcmpt=image->cmpts_[0]; /* printf(" SAGOUT DECODE:\n"); printf(" tlx %d \n",image->tlx_); printf(" tly %d \n",image->tly_); printf(" brx %d \n",image->brx_); printf(" bry %d \n",image->bry_); printf(" numcmpts %d \n",image->numcmpts_); printf(" maxcmpts %d \n",image->maxcmpts_); #ifdef JAS_1_500_4 printf(" colormodel %d \n",image->colormodel_); #endif #ifdef JAS_1_700_2 printf(" colorspace %d \n",image->clrspc_); #endif printf(" inmem %d \n",image->inmem_); printf(" COMPONENT:\n"); printf(" tlx %d \n",pcmpt->tlx_); printf(" tly %d \n",pcmpt->tly_); printf(" hstep %d \n",pcmpt->hstep_); printf(" vstep %d \n",pcmpt->vstep_); printf(" width %d \n",pcmpt->width_); printf(" height %d \n",pcmpt->height_); printf(" prec %d \n",pcmpt->prec_); printf(" sgnd %d \n",pcmpt->sgnd_); printf(" cps %d \n",pcmpt->cps_); #ifdef JAS_1_700_2 printf(" type %d \n",pcmpt->type_); #endif */ // Expecting jpeg2000 image to be grayscale only. // No color components. // if (image->numcmpts_ != 1 ) { printf("dec_jpeg2000: Found color image. Grayscale expected.\n"); return (-5); } // // Create a data matrix of grayscale image values decoded from // the jpeg2000 codestream. // data=jas_matrix_create(jas_image_height(image), jas_image_width(image)); jas_image_readcmpt(image,0,0,0,jas_image_width(image), jas_image_height(image),data); // // Copy data matrix to output integer array. // k=0; for (i=0;i<pcmpt->height_;i++) for (j=0;j<pcmpt->width_;j++) outfld[k++]=data->rows_[i][j]; // // Clean up JasPer work structures. // jas_matrix_destroy(data); ier=jas_stream_close(jpcstream); jas_image_destroy(image); return 0; } #endif /* USE_JPEG2000 */ g2clib-1.6.0/dec_png.c0000644002373300042670000000711012522400360014257 0ustar Boi.Vuongglobal#ifndef USE_PNG void dummy(void) {} #else /* USE_PNG */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <png.h> #include "grib2.h" struct png_stream { unsigned char *stream_ptr; /* location to write PNG stream */ g2int stream_len; /* number of bytes written */ }; typedef struct png_stream png_stream; void user_read_data(png_structp , png_bytep , png_uint_32 ); void user_read_data(png_structp png_ptr,png_bytep data, png_uint_32 length) /* Custom read function used so that libpng will read a PNG stream from memory instead of a file on disk. */ { char *ptr; g2int offset; png_stream *mem; mem=(png_stream *)png_get_io_ptr(png_ptr); ptr=(void *)mem->stream_ptr; offset=mem->stream_len; /* printf("SAGrd %ld %ld %x\n",offset,length,ptr); */ memcpy(data,ptr+offset,length); mem->stream_len += length; } int dec_png(unsigned char *pngbuf,g2int *width,g2int *height,char *cout) { int interlace,color,compres,filter,bit_depth; g2int j,k,n,bytes,clen; png_structp png_ptr; png_infop info_ptr,end_info; png_bytepp row_pointers; png_stream read_io_ptr; png_uint_32 h32, w32; /* check if stream is a valid PNG format */ if ( png_sig_cmp(pngbuf,0,8) != 0) return (-3); /* create and initialize png_structs */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL); if (!png_ptr) return (-1); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr,(png_infopp)NULL,(png_infopp)NULL); return (-2); } end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr,(png_infopp)info_ptr,(png_infopp)NULL); return (-2); } /* Set Error callback */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr,&end_info); return (-3); } /* Initialize info for reading PNG stream from memory */ read_io_ptr.stream_ptr=(png_voidp)pngbuf; read_io_ptr.stream_len=0; /* Set new custom read function */ png_set_read_fn(png_ptr,(png_voidp)&read_io_ptr,(png_rw_ptr)user_read_data); /* png_init_io(png_ptr, fptr); */ /* Read and decode PNG stream */ png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); /* Get pointer to each row of image data */ row_pointers = png_get_rows(png_ptr, info_ptr); /* Get image info, such as size, depth, colortype, etc... */ /*printf("SAGT:png %d %d %d\n",info_ptr->width,info_ptr->height,info_ptr->bit_depth);*/ // (void)png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *)width, (png_uint_32 *)height, (void)png_get_IHDR(png_ptr, info_ptr, &w32, &h32, &bit_depth, &color, &interlace, &compres, &filter); *height = h32; *width = w32; /* Check if image was grayscale */ /* if (color != PNG_COLOR_TYPE_GRAY ) { fprintf(stderr,"dec_png: Grayscale image was expected. \n"); } */ if ( color == PNG_COLOR_TYPE_RGB ) { bit_depth=24; } else if ( color == PNG_COLOR_TYPE_RGB_ALPHA ) { bit_depth=32; } /* Copy image data to output string */ n=0; bytes=bit_depth/8; clen=(*width)*bytes; for (j=0;j<*height;j++) { for (k=0;k<clen;k++) { cout[n]=*(row_pointers[j]+k); n++; } } /* Clean up */ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); return 0; } #endif /* USE_PNG */ g2clib-1.6.0/drstemplates.c0000755002373300042670000001121412522400360015372 0ustar Boi.Vuongglobal#include <stdlib.h> #include "grib2.h" #include "drstemplates.h" g2int getdrsindex(g2int number) /*!$$$ SUBPROGRAM DOCUMENTATION BLOCK ! . . . . ! SUBPROGRAM: getdrsindex ! PRGMMR: Gilbert ORG: W/NP11 DATE: 2001-06-28 ! ! ABSTRACT: This function returns the index of specified Data ! Representation Template 5.NN (NN=number) in array templates. ! ! PROGRAM HISTORY LOG: ! 2001-06-28 Gilbert ! 2009-01-14 Vuong Changed structure name template to gtemplate ! ! USAGE: index=getdrsindex(number) ! INPUT ARGUMENT LIST: ! number - NN, indicating the number of the Data Representation ! Template 5.NN that is being requested. ! ! RETURNS: Index of DRT 5.NN in array gtemplates, if gtemplate exists. ! = -1, otherwise. ! ! REMARKS: None ! ! ATTRIBUTES: ! LANGUAGE: C ! MACHINE: IBM SP ! !$$$*/ { g2int j,getdrsindex=-1; for (j=0;j<MAXDRSTEMP;j++) { if (number == templatesdrs[j].template_num) { getdrsindex=j; return(getdrsindex); } } return(getdrsindex); } gtemplate *getdrstemplate(g2int number) /*!$$$ SUBPROGRAM DOCUMENTATION BLOCK ! . . . . ! SUBPROGRAM: getdrstemplate ! PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-05-11 ! ! ABSTRACT: This subroutine returns DRS template information for a ! specified Data Representation Template 5.NN. ! The number of entries in the template is returned along with a map ! of the number of octets occupied by each entry. Also, a flag is ! returned to indicate whether the template would need to be extended. ! ! PROGRAM HISTORY LOG: ! 2000-05-11 Gilbert ! 2009-01-14 Vuong Changed structure name template to gtemplate ! ! USAGE: new=getdrstemplate(number); ! INPUT ARGUMENT LIST: ! number - NN, indicating the number of the Data Representation ! Template 5.NN that is being requested. ! ! RETURN VALUE: ! - Pointer to the returned template struct. ! Returns NULL pointer, if template not found. ! ! REMARKS: None ! ! ATTRIBUTES: ! LANGUAGE: C ! MACHINE: IBM SP ! !$$$*/ { g2int index; gtemplate *new; index=getdrsindex(number); if (index != -1) { new=(gtemplate *)malloc(sizeof(gtemplate)); new->type=5; new->num=templatesdrs[index].template_num; new->maplen=templatesdrs[index].mapdrslen; new->needext=templatesdrs[index].needext; new->map=(g2int *)templatesdrs[index].mapdrs; new->extlen=0; new->ext=0; //NULL return(new); } else { printf("getdrstemplate: DRS Template 5.%d not defined.\n",(int)number); return(0); //NULL } return(0); //NULL } gtemplate *extdrstemplate(g2int number,g2int *list) /*!$$$ SUBPROGRAM DOCUMENTATION BLOCK ! . . . . ! SUBPROGRAM: extdrstemplate ! PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-05-11 ! ! ABSTRACT: This subroutine generates the remaining octet map for a ! given Data Representation Template, if required. Some Templates can ! vary depending on data values given in an earlier part of the ! Template, and it is necessary to know some of the earlier entry ! values to generate the full octet map of the Template. ! ! PROGRAM HISTORY LOG: ! 2000-05-11 Gilbert ! 2009-01-14 Vuong Changed structure name template to gtemplate ! ! USAGE: new=extdrstemplate(number,list); ! INPUT ARGUMENT LIST: ! number - NN, indicating the number of the Data Representation ! Template 5.NN that is being requested. ! list() - The list of values for each entry in the ! the Data Representation Template 5.NN. ! ! RETURN VALUE: ! - Pointer to the returned template struct. ! Returns NULL pointer, if template not found. ! ! ATTRIBUTES: ! LANGUAGE: C ! MACHINE: IBM SP ! !$$$*/ { gtemplate *new; g2int index,i; index=getdrsindex(number); if (index == -1) return(0); new=getdrstemplate(number); if ( ! new->needext ) return(new); if ( number == 1 ) { new->extlen=list[10]+list[12]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { new->ext[i]=4; } } return(new); } g2clib-1.6.0/drstemplates.h0000755002373300042670000000603512522400360015404 0ustar Boi.Vuongglobal#ifndef _drstemplates_H #define _drstemplates_H #include "grib2.h" // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-26 // // ABSTRACT: This Fortran Module contains info on all the available // GRIB2 Data Representation Templates used in Section 5 (DRS). // The information decribing each template is stored in the // drstemplate structure defined below. // // Each Template has three parts: The number of entries in the template // (mapdrslen); A map of the template (mapdrs), which contains the // number of octets in which to pack each of the template values; and // a logical value (needext) that indicates whether the Template needs // to be extended. In some cases the number of entries in a template // can vary depending upon values specified in the "static" part of // the template. ( See Template 5.1 as an example ) // // NOTE: Array mapdrs contains the number of octets in which the // corresponding template values will be stored. A negative value in // mapdrs is used to indicate that the corresponding template entry can // contain negative values. This information is used later when packing // (or unpacking) the template data values. Negative data values in GRIB // are stored with the left most bit set to one, and a negative number // of octets value in mapdrs[] indicates that this possibility should // be considered. The number of octets used to store the data value // in this case would be the absolute value of the negative value in // mapdrs[]. // // /////////////////////////////////////////////////////////////////////// #define MAXDRSTEMP 9 // maximum number of templates #define MAXDRSMAPLEN 200 // maximum template map length struct drstemplate { g2int template_num; g2int mapdrslen; g2int needext; g2int mapdrs[MAXDRSMAPLEN]; }; const struct drstemplate templatesdrs[MAXDRSTEMP] = { // 5.0: Grid point data - Simple Packing { 0, 5, 0, {4,-2,-2,1,1} }, // 5.2: Grid point data - Complex Packing { 2, 16, 0, {4,-2,-2,1,1,1,1,4,4,4,1,1,4,1,4,1} }, // 5.3: Grid point data - Complex Packing and spatial differencing { 3, 18, 0, {4,-2,-2,1,1,1,1,4,4,4,1,1,4,1,4,1,1,1} }, // 5.50: Spectral Data - Simple Packing { 50, 5, 0, {4,-2,-2,1,4} }, // 5.51: Spherical Harmonics data - Complex packing { 51, 10, 0, {4,-2,-2,1,-4,2,2,2,4,1} }, // // 5.1: Matrix values at gridpoint - Simple packing // { 1, 15, 1, {4,-2,-2,1,1,1,4,2,2,1,1,1,1,1,1} }, // 5.40: Grid point data - JPEG2000 encoding { 40, 7, 0, {4,-2,-2,1,1,1,1} }, // 5.41: Grid point data - PNG encoding { 41, 5, 0, {4,-2,-2,1,1} }, // 5.40000: Grid point data - JPEG2000 encoding { 40000, 7, 0, {4,-2,-2,1,1,1,1} }, // 5.40010: Grid point data - PNG encoding { 40010, 5, 0, {4,-2,-2,1,1} } } ; #endif /* _drstemplates_H */ g2clib-1.6.0/enc_jpeg2000.c0000644002373300042670000001207112522400360014736 0ustar Boi.Vuongglobal#ifndef USE_JPEG2000 void dummy(void) {} #else /* USE_JPEG2000 */ #include <stdio.h> #include <stdlib.h> #include "grib2.h" #include "jasper/jasper.h" #define JAS_1_700_2 int enc_jpeg2000(unsigned char *cin,g2int width,g2int height,g2int nbits, g2int ltype, g2int ratio, g2int retry, char *outjpc, g2int jpclen) /*$$$ SUBPROGRAM DOCUMENTATION BLOCK * . . . . * SUBPROGRAM: enc_jpeg2000 Encodes JPEG2000 code stream * PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-02 * * ABSTRACT: This Function encodes a grayscale image into a JPEG2000 code stream * specified in the JPEG2000 Part-1 standard (i.e., ISO/IEC 15444-1) * using JasPer Software version 1.500.4 (or 1.700.2 ) written by the * University of British Columbia, Image Power Inc, and others. * JasPer is available at http://www.ece.uvic.ca/~mdadams/jasper/. * * PROGRAM HISTORY LOG: * 2002-12-02 Gilbert * 2004-12-16 Gilbert - Added retry argument/option to allow option of * increasing the maximum number of guard bits to the * JPEG2000 algorithm. * * USAGE: int enc_jpeg2000(unsigned char *cin,g2int width,g2int height, * g2int nbits, g2int ltype, g2int ratio, * g2int retry, char *outjpc, g2int jpclen) * * INPUT ARGUMENTS: * cin - Packed matrix of Grayscale image values to encode. * width - width of image * height - height of image * nbits - depth (in bits) of image. i.e number of bits * used to hold each data value * ltype - indicator of lossless or lossy compression * = 1, for lossy compression * != 1, for lossless compression * ratio - target compression ratio. (ratio:1) * Used only when ltype == 1. * retry - Pointer to option type. * 1 = try increasing number of guard bits * otherwise, no additional options * jpclen - Number of bytes allocated for new JPEG2000 code stream in * outjpc. * * INPUT ARGUMENTS: * outjpc - Output encoded JPEG2000 code stream * * RETURN VALUES : * > 0 = Length in bytes of encoded JPEG2000 code stream * -3 = Error decode jpeg2000 code stream. * -5 = decoded image had multiple color components. * Only grayscale is expected. * * REMARKS: * * Requires JasPer Software version 1.500.4 or 1.700.2 * * ATTRIBUTES: * LANGUAGE: C * MACHINE: IBM SP * *$$$*/ { int ier,rwcnt; jas_image_t image; jas_stream_t *jpcstream,*istream; jas_image_cmpt_t cmpt,*pcmpt; #define MAXOPTSSIZE 1024 char opts[MAXOPTSSIZE]; /* printf(" enc_jpeg2000:width %ld\n",width); printf(" enc_jpeg2000:height %ld\n",height); printf(" enc_jpeg2000:nbits %ld\n",nbits); printf(" enc_jpeg2000:jpclen %ld\n",jpclen); */ // jas_init(); // // Set lossy compression options, if requested. // if ( ltype != 1 ) { opts[0]=(char)0; } else { snprintf(opts,MAXOPTSSIZE,"mode=real\nrate=%f",1.0/(float)ratio); } if ( retry == 1 ) { // option to increase number of guard bits strcat(opts,"\nnumgbits=4"); } //printf("SAGopts: %s\n",opts); // // Initialize the JasPer image structure describing the grayscale // image to encode into the JPEG2000 code stream. // image.tlx_=0; image.tly_=0; #ifdef JAS_1_500_4 image.brx_=(uint_fast32_t)width; image.bry_=(uint_fast32_t)height; #endif #ifdef JAS_1_700_2 image.brx_=(jas_image_coord_t)width; image.bry_=(jas_image_coord_t)height; #endif image.numcmpts_=1; image.maxcmpts_=1; #ifdef JAS_1_500_4 image.colormodel_=JAS_IMAGE_CM_GRAY; /* grayscale Image */ #endif #ifdef JAS_1_700_2 image.clrspc_=JAS_CLRSPC_SGRAY; /* grayscale Image */ image.cmprof_=0; #endif image.inmem_=1; cmpt.tlx_=0; cmpt.tly_=0; cmpt.hstep_=1; cmpt.vstep_=1; #ifdef JAS_1_500_4 cmpt.width_=(uint_fast32_t)width; cmpt.height_=(uint_fast32_t)height; #endif #ifdef JAS_1_700_2 cmpt.width_=(jas_image_coord_t)width; cmpt.height_=(jas_image_coord_t)height; cmpt.type_=JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y); #endif cmpt.prec_=nbits; cmpt.sgnd_=0; cmpt.cps_=(nbits+7)/8; pcmpt=&cmpt; image.cmpts_=&pcmpt; // // Open a JasPer stream containing the input grayscale values // istream=jas_stream_memopen((char *)cin,height*width*cmpt.cps_); cmpt.stream_=istream; // // Open an output stream that will contain the encoded jpeg2000 // code stream. // jpcstream=jas_stream_memopen(outjpc,(int)jpclen); // // Encode image. // ier=jpc_encode(&image,jpcstream,opts); if ( ier != 0 ) { printf(" jpc_encode return = %d \n",ier); return -3; } // // Clean up JasPer work structures. // rwcnt=jpcstream->rwcnt_; ier=jas_stream_close(istream); ier=jas_stream_close(jpcstream); // // Return size of jpeg2000 code stream // return (rwcnt); } #endif /* USE_JPEG2000 */ g2clib-1.6.0/enc_png.c0000644002373300042670000000672712522400360014306 0ustar Boi.Vuongglobal#ifndef USE_PNG void dummy(void) {} #else /* USE_PNG */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <png.h> #include "grib2.h" struct png_stream { unsigned char *stream_ptr; /* location to write PNG stream */ g2int stream_len; /* number of bytes written */ }; typedef struct png_stream png_stream; void user_write_data(png_structp ,png_bytep , png_uint_32 ); void user_flush_data(png_structp ); void user_write_data(png_structp png_ptr,png_bytep data, png_uint_32 length) /* Custom write function used to that libpng will write to memory location instead of a file on disk */ { unsigned char *ptr; g2int offset; png_stream *mem; mem=(png_stream *)png_get_io_ptr(png_ptr); ptr=mem->stream_ptr; offset=mem->stream_len; /* printf("SAGwr %ld %ld %x\n",offset,length,ptr); */ /*for (j=offset,k=0;k<length;j++,k++) ptr[j]=data[k];*/ memcpy(ptr+offset,data,length); mem->stream_len += length; } void user_flush_data(png_structp png_ptr) /* Dummy Custom flush function */ { int *do_nothing; do_nothing=NULL; } int enc_png(char *data,g2int width,g2int height,g2int nbits,char *pngbuf) { int color_type; g2int j,bytes,pnglen,bit_depth; png_structp png_ptr; png_infop info_ptr; // png_bytep *row_pointers[height]; png_bytep **row_pointers; png_stream write_io_ptr; /* create and initialize png_structs */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL); if (!png_ptr) return (-1); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr,(png_infopp)NULL); return (-2); } /* Set Error callback */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); return (-3); } /* Initialize info for writing PNG stream to memory */ write_io_ptr.stream_ptr=(png_voidp)pngbuf; write_io_ptr.stream_len=0; /* Set new custom write functions */ png_set_write_fn(png_ptr,(png_voidp)&write_io_ptr,(png_rw_ptr)user_write_data, (png_flush_ptr)user_flush_data); /* png_init_io(png_ptr, fptr); */ /* png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); */ /* Set the image size, colortype, filter type, etc... */ /* printf("SAGTsettingIHDR %d %d %d\n",width,height,bit_depth); */ bit_depth=nbits; color_type=PNG_COLOR_TYPE_GRAY; if (nbits == 24 ) { bit_depth=8; color_type=PNG_COLOR_TYPE_RGB; } else if (nbits == 32 ) { bit_depth=8; color_type=PNG_COLOR_TYPE_RGB_ALPHA; } png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); /* Put image data into the PNG info structure */ /*bytes=bit_depth/8;*/ bytes=nbits/8; row_pointers=malloc(height*sizeof(png_bytep)); for (j=0;j<height;j++) row_pointers[j]=(png_bytep *)(data+(j*width*bytes)); png_set_rows(png_ptr, info_ptr, (png_bytepp)row_pointers); /* Do the PNG encoding, and write out PNG stream */ png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); /* Clean up */ png_destroy_write_struct(&png_ptr, &info_ptr); free(row_pointers); pnglen=write_io_ptr.stream_len; return pnglen; } #endif /* USE_PNG */ g2clib-1.6.0/g2_addfield.c0000755002373300042670000004534212522400360015020 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" g2int getdim(unsigned char *,g2int *,g2int *,g2int *); g2int getpoly(unsigned char *,g2int *,g2int *,g2int *); void simpack(g2float *, g2int, g2int *, unsigned char *, g2int *); void cmplxpack(g2float *, g2int, g2int, g2int *, unsigned char *, g2int *); void specpack(g2float *,g2int,g2int,g2int,g2int,g2int *,unsigned char *, g2int *); #ifdef USE_PNG void pngpack(g2float *,g2int,g2int,g2int *,unsigned char *,g2int *); #endif /* USE_PNG */ #ifdef USE_JPEG2000 void jpcpack(g2float *,g2int,g2int,g2int *,unsigned char *,g2int *); #endif /* USE_JPEG2000 */ g2int 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) //$$$ 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 // 2002-12-23 Gilbert - Added complex spherical harmonic packing // 2003-08-27 Gilbert - Added support for new templates using // PNG and JPEG2000 algorithms/templates. // 2004-11-29 Gilbert - JPEG2000 now allowed to use WMO Template no. 5.40 // PNG now allowed to use WMO Template no. 5.41 // - Added check to determine if packing algorithm failed. // 2005-05-10 Gilbert - Imposed minimum size on cpack, used to hold encoded // bit string. // 2009-01-14 Vuong Changed structure name template to gtemplate // // 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 g2_create 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. // -9 = GDT of one of 5.50 through 5.53 required to pack field // using DRT 5.51. // -10 = Error packing data field. // // REMARKS: Note that the Sections 4 through 7 can only follow // Section 3 or Section 7 in a GRIB2 message. // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$ { g2int ierr; static unsigned char G=0x47; // 'G' static unsigned char R=0x52; // 'R' static unsigned char I=0x49; // 'I' static unsigned char B=0x42; // 'B' static unsigned char s7=0x37; // '7' unsigned char *cpack; static g2int zero=0,one=1,four=4,five=5,six=6,seven=7; const g2int minsize=50000; g2int iofst,ibeg,lencurr,len,nsize; g2int ilen,isecnum,i,nbits,temp,left; g2int ibmprev,j,lcpack,ioctet,newlen,ndpts; g2int lensec4,lensec5,lensec6,lensec7; g2int issec3,isprevbmap,lpos3=0,JJ,KK,MM; g2int *coordieee; g2int width,height,iscan,itemp; g2float *pfld; gtemplate *mappds,*mapdrs; unsigned int allones=4294967295u; ierr=0; // // Check to see if beginning of GRIB message exists // if ( cgrib[0]!=G || cgrib[1]!=R || cgrib[2]!=I || cgrib[3]!=B ) { printf("g2_addfield: GRIB not found in given message.\n"); printf("g2_addfield: Call to routine g2_create required to initialize GRIB messge.\n"); ierr=-1; return(ierr); } // // Get current length of GRIB message // gbit(cgrib,&lencurr,96,32); // // Check to see if GRIB message is already complete // if ( cgrib[lencurr-4]==s7 && cgrib[lencurr-3]==s7 && cgrib[lencurr-2]==s7 && cgrib[lencurr-1]==s7 ) { printf("g2_addfield: GRIB message already complete. Cannot add new section.\n"); ierr=-2; return(ierr); } // // Loop through all current sections of the GRIB message to // find the last section number. // issec3=0; isprevbmap=0; len=16; // length of Section 0 for (;;) { // Get number and length of next section iofst=len*8; gbit(cgrib,&ilen,iofst,32); iofst=iofst+32; gbit(cgrib,&isecnum,iofst,8); iofst=iofst+8; // Check if previous Section 3 exists if (isecnum == 3) { issec3=1; lpos3=len; } // Check if a previous defined bitmap exists if (isecnum == 6) { gbit(cgrib,&ibmprev,iofst,8); iofst=iofst+8; if ((ibmprev >= 0) && (ibmprev <= 253)) isprevbmap=1; } len=len+ilen; // Exit loop if last section reached if ( len == lencurr ) break; // If byte count for each section doesn't match current // total length, then there is a problem. if ( len > lencurr ) { printf("g2_addfield: Section byte counts don''t add to total.\n"); printf("g2_addfield: Sum of section byte counts = %ld\n",len); printf("g2_addfield: Total byte count in Section 0 = %ld\n",lencurr); ierr=-3; return(ierr); } } // // Sections 4 through 7 can only be added after section 3 or 7. // if ( (isecnum != 3) && (isecnum != 7) ) { printf("g2_addfield: Sections 4-7 can only be added after Section 3 or 7.\n"); printf("g2_addfield: Section ',isecnum,' was the last found in given GRIB message.\n"); ierr=-4; return(ierr); // // Sections 4 through 7 can only be added if section 3 was previously defined. // } else if ( ! issec3) { printf("g2_addfield: Sections 4-7 can only be added if Section 3 was previously included.\n"); printf("g2_addfield: Section 3 was not found in given GRIB message.\n"); printf("g2_addfield: Call to routine addgrid required to specify Grid definition.\n"); ierr=-6; return(ierr); } // // Add Section 4 - Product Definition Section // ibeg=lencurr*8; // Calculate offset for beginning of section 4 iofst=ibeg+32; // leave space for length of section sbit(cgrib,&four,iofst,8); // Store section number ( 4 ) iofst=iofst+8; sbit(cgrib,&numcoord,iofst,16); // Store num of coordinate values iofst=iofst+16; sbit(cgrib,&ipdsnum,iofst,16); // Store Prod Def Template num. iofst=iofst+16; // // Get Product Definition Template // mappds=getpdstemplate(ipdsnum); if (mappds == 0) { // undefined template ierr=-5; return(ierr); } // // Extend the Product Definition Template, if necessary. // The number of values in a specific template may vary // depending on data specified in the "static" part of the // template. // if ( mappds->needext ) { free(mappds); mappds=extpdstemplate(ipdsnum,ipdstmpl); } // // Pack up each input value in array ipdstmpl into the // the appropriate number of octets, which are specified in // corresponding entries in array mappds. // for (i=0;i<mappds->maplen;i++) { nbits=abs(mappds->map[i])*8; if ( (mappds->map[i] >= 0) || (ipdstmpl[i] >= 0) ) sbit(cgrib,ipdstmpl+i,iofst,nbits); else { sbit(cgrib,&one,iofst,1); temp=abs(ipdstmpl[i]); sbit(cgrib,&temp,iofst+1,nbits-1); } iofst=iofst+nbits; } // Pack template extension, if appropriate j=mappds->maplen; if ( mappds->needext && (mappds->extlen > 0) ) { for (i=0;i<mappds->extlen;i++) { nbits=abs(mappds->ext[i])*8; if ( (mappds->ext[i] >= 0) || (ipdstmpl[j] >= 0) ) sbit(cgrib,ipdstmpl+j,iofst,nbits); else { sbit(cgrib,&one,iofst,1); temp=abs(ipdstmpl[j]); sbit(cgrib,&temp,iofst+1,nbits-1); } iofst=iofst+nbits; j++; } } free(mappds); // // Add Optional list of vertical coordinate values // after the Product Definition Template, if necessary. // if ( numcoord != 0 ) { coordieee=(g2int *)calloc(numcoord,sizeof(g2int)); mkieee(coordlist,coordieee,numcoord); sbits(cgrib,coordieee,iofst,32,0,numcoord); iofst=iofst+(32*numcoord); free(coordieee); } // // Calculate length of section 4 and store it in octets // 1-4 of section 4. // lensec4=(iofst-ibeg)/8; sbit(cgrib,&lensec4,ibeg,32); // // Pack Data using appropriate algorithm // // // Get Data Representation Template // mapdrs=getdrstemplate(idrsnum); if (mapdrs == 0) { ierr=-5; return(ierr); } // // contract data field, removing data at invalid grid points, // if bit-map is provided with field. // if ( ibmap == 0 || ibmap==254 ) { pfld=(g2float *)malloc(ngrdpts*sizeof(g2float)); ndpts=0; for (j=0;j<ngrdpts;j++) { if ( bmap[j]==1 ) pfld[ndpts++]=fld[j]; } } else { ndpts=ngrdpts; pfld=fld; } nsize=ndpts*4; if ( nsize < minsize ) nsize=minsize; cpack=malloc(nsize); if (idrsnum == 0) // Simple Packing simpack(pfld,ndpts,idrstmpl,cpack,&lcpack); else if (idrsnum==2 || idrsnum==3) // Complex Packing cmplxpack(pfld,ndpts,idrsnum,idrstmpl,cpack,&lcpack); else if (idrsnum == 50) { // Sperical Harmonic Simple Packing simpack(pfld+1,ndpts-1,idrstmpl,cpack,&lcpack); mkieee(pfld+0,idrstmpl+4,1); // ensure RE(0,0) value is IEEE format } else if (idrsnum == 51) { // Sperical Harmonic Complex Packing getpoly(cgrib+lpos3,&JJ,&KK,&MM); if ( JJ!=0 && KK!=0 && MM!=0 ) specpack(pfld,ndpts,JJ,KK,MM,idrstmpl,cpack,&lcpack); else { printf("g2_addfield: Cannot pack DRT 5.51.\n"); return (-9); } } #ifdef USE_JPEG2000 else if (idrsnum == 40 || idrsnum == 40000) { /* JPEG2000 encoding */ if (ibmap == 255) { getdim(cgrib+lpos3,&width,&height,&iscan); if ( width==0 || height==0 ) { width=ndpts; height=1; } else if ( width==allones || height==allones ) { width=ndpts; height=1; } else if ( (iscan&32) == 32) { /* Scanning mode: bit 3 */ itemp=width; width=height; height=itemp; } } else { width=ndpts; height=1; } lcpack=nsize; jpcpack(pfld,width,height,idrstmpl,cpack,&lcpack); } #endif /* USE_JPEG2000 */ #ifdef USE_PNG else if (idrsnum == 41 || idrsnum == 40010) { /* PNG encoding */ if (ibmap == 255) { getdim(cgrib+lpos3,&width,&height,&iscan); if ( width==0 || height==0 ) { width=ndpts; height=1; } else if ( width==allones || height==allones ) { width=ndpts; height=1; } else if ( (iscan&32) == 32) { /* Scanning mode: bit 3 */ itemp=width; width=height; height=itemp; } } else { width=ndpts; height=1; } pngpack(pfld,width,height,idrstmpl,cpack,&lcpack); } #endif /* USE_PNG */ else { printf("g2_addfield: Data Representation Template 5.%ld not yet implemented.\n",idrsnum); ierr=-7; return(ierr); } if ( ibmap == 0 || ibmap==254 ) { // free temp space if (fld != pfld) free(pfld); } if ( lcpack < 0 ) { if( cpack != 0 ) free(cpack); ierr=-10; return(ierr); } // // Add Section 5 - Data Representation Section // ibeg=iofst; // Calculate offset for beginning of section 5 iofst=ibeg+32; // leave space for length of section sbit(cgrib,&five,iofst,8); // Store section number ( 5 ) iofst=iofst+8; sbit(cgrib,&ndpts,iofst,32); // Store num of actual data points iofst=iofst+32; sbit(cgrib,&idrsnum,iofst,16); // Store Data Repr. Template num. iofst=iofst+16; // // Pack up each input value in array idrstmpl into the // the appropriate number of octets, which are specified in // corresponding entries in array mapdrs. // for (i=0;i<mapdrs->maplen;i++) { nbits=abs(mapdrs->map[i])*8; if ( (mapdrs->map[i] >= 0) || (idrstmpl[i] >= 0) ) sbit(cgrib,idrstmpl+i,iofst,nbits); else { sbit(cgrib,&one,iofst,1); temp=abs(idrstmpl[i]); sbit(cgrib,&temp,iofst+1,nbits-1); } iofst=iofst+nbits; } free(mapdrs); // // Calculate length of section 5 and store it in octets // 1-4 of section 5. // lensec5=(iofst-ibeg)/8; sbit(cgrib,&lensec5,ibeg,32); // // Add Section 6 - Bit-Map Section // ibeg=iofst; // Calculate offset for beginning of section 6 iofst=ibeg+32; // leave space for length of section sbit(cgrib,&six,iofst,8); // Store section number ( 6 ) iofst=iofst+8; sbit(cgrib,&ibmap,iofst,8); // Store Bit Map indicator iofst=iofst+8; // // Store bitmap, if supplied // if (ibmap == 0) { sbits(cgrib,bmap,iofst,1,0,ngrdpts); // Store BitMap iofst=iofst+ngrdpts; } // // If specifying a previously defined bit-map, make sure // one already exists in the current GRIB message. // if ((ibmap==254) && ( ! isprevbmap)) { printf("g2_addfield: Requested previously defined bitmap,"); printf(" but one does not exist in the current GRIB message.\n"); ierr=-8; return(ierr); } // // Calculate length of section 6 and store it in octets // 1-4 of section 6. Pad to end of octect, if necessary. // left=8-(iofst%8); if (left != 8) { sbit(cgrib,&zero,iofst,left); // Pad with zeros to fill Octet iofst=iofst+left; } lensec6=(iofst-ibeg)/8; sbit(cgrib,&lensec6,ibeg,32); // // Add Section 7 - Data Section // ibeg=iofst; // Calculate offset for beginning of section 7 iofst=ibeg+32; // leave space for length of section sbit(cgrib,&seven,iofst,8); // Store section number ( 7 ) iofst=iofst+8; // Store Packed Binary Data values, if non-constant field if (lcpack != 0) { ioctet=iofst/8; //cgrib(ioctet+1:ioctet+lcpack)=cpack(1:lcpack) for (j=0;j<lcpack;j++) cgrib[ioctet+j]=cpack[j]; iofst=iofst+(8*lcpack); } // // Calculate length of section 7 and store it in octets // 1-4 of section 7. // lensec7=(iofst-ibeg)/8; sbit(cgrib,&lensec7,ibeg,32); if( cpack != 0 ) free(cpack); // // Update current byte total of message in Section 0 // newlen=lencurr+lensec4+lensec5+lensec6+lensec7; sbit(cgrib,&newlen,96,32); return(newlen); } g2clib-1.6.0/g2_addgrid.c0000755002373300042670000002200012522400360014644 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" g2int g2_addgrid(unsigned char *cgrib,g2int *igds,g2int *igdstmpl,g2int *ideflist,g2int idefnum) //$$$ 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 // 2009-01-14 Vuong Changed structure name template to gtemplate // // USAGE: int g2_addgrid(unsigned char *cgrib,g2int *igds,g2int *igdstmpl, // g2int *ideflist,g2int 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: // //$$$ { g2int ierr; static unsigned char G=0x47; // 'G' static unsigned char R=0x52; // 'R' static unsigned char I=0x49; // 'I' static unsigned char B=0x42; // 'B' static unsigned char seven=0x37; // '7' static g2int one=1,three=3,miss=65535; g2int lensec3,iofst,ibeg,lencurr,len; g2int i,j,temp,ilen,isecnum,nbits; gtemplate *mapgrid=0; ierr=0; // // Check to see if beginning of GRIB message exists // if ( cgrib[0]!=G || cgrib[1]!=R || cgrib[2]!=I || cgrib[3]!=B ) { printf("g2_addgrid: GRIB not found in given message.\n"); printf("g2_addgrid: Call to routine gribcreate required to initialize GRIB messge.\n"); ierr=-1; return(ierr); } // // Get current length of GRIB message // gbit(cgrib,&lencurr,96,32); // // Check to see if GRIB message is already complete // if ( cgrib[lencurr-4]==seven && cgrib[lencurr-3]==seven && cgrib[lencurr-2]==seven && cgrib[lencurr-1]==seven ) { printf("g2_addgrid: GRIB message already complete. Cannot add new section.\n"); ierr=-2; return(ierr); } // // Loop through all current sections of the GRIB message to // find the last section number. // len=16; // length of Section 0 for (;;) { // Get section number and length of next section iofst=len*8; gbit(cgrib,&ilen,iofst,32); iofst=iofst+32; gbit(cgrib,&isecnum,iofst,8); len=len+ilen; // Exit loop if last section reached if ( len == lencurr ) break; // If byte count for each section doesn't match current // total length, then there is a problem. if ( len > lencurr ) { printf("g2_addgrid: Section byte counts don''t add to total.\n"); printf("g2_addgrid: Sum of section byte counts = %ld\n",len); printf("g2_addgrid: Total byte count in Section 0 = %ld\n",lencurr); ierr=-3; return(ierr); } } // // Section 3 can only be added after sections 1, 2 and 7. // if ( (isecnum!=1) && (isecnum!=2) && (isecnum!=7) ) { printf("g2_addgrid: Section 3 can only be added after Section 1, 2 or 7.\n"); printf("g2_addgrid: Section ',isecnum,' was the last found in given GRIB message.\n"); ierr=-4; return(ierr); } // // Add Section 3 - Grid Definition Section // ibeg=lencurr*8; // Calculate offset for beginning of section 3 iofst=ibeg+32; // leave space for length of section sbit(cgrib,&three,iofst,8); // Store section number ( 3 ) iofst=iofst+8; sbit(cgrib,igds+0,iofst,8); // Store source of Grid def. iofst=iofst+8; sbit(cgrib,igds+1,iofst,32); // Store number of data pts. iofst=iofst+32; sbit(cgrib,igds+2,iofst,8); // Store number of extra octets. iofst=iofst+8; sbit(cgrib,igds+3,iofst,8); // Store interp. of extra octets. iofst=iofst+8; // if Octet 6 is not equal to zero, Grid Definition Template may // not be supplied. if ( igds[0] == 0 ) sbit(cgrib,igds+4,iofst,16); // Store Grid Def Template num. else sbit(cgrib,&miss,iofst,16); // Store missing value as Grid Def Template num. iofst=iofst+16; // // Get Grid Definition Template // if (igds[0] == 0) { mapgrid=getgridtemplate(igds[4]); if (mapgrid == 0) { // undefined template ierr=-5; return(ierr); } // // Extend the Grid Definition Template, if necessary. // The number of values in a specific template may vary // depending on data specified in the "static" part of the // template. // if ( mapgrid->needext ) { free(mapgrid); mapgrid=extgridtemplate(igds[4],igdstmpl); } } // // Pack up each input value in array igdstmpl into the // the appropriate number of octets, which are specified in // corresponding entries in array mapgrid. // for (i=0;i<mapgrid->maplen;i++) { nbits=abs(mapgrid->map[i])*8; if ( (mapgrid->map[i] >= 0) || (igdstmpl[i] >= 0) ) sbit(cgrib,igdstmpl+i,iofst,nbits); else { sbit(cgrib,&one,iofst,1); temp=abs(igdstmpl[i]); sbit(cgrib,&temp,iofst+1,nbits-1); } iofst=iofst+nbits; } // Pack template extension, if appropriate j=mapgrid->maplen; if ( mapgrid->needext && (mapgrid->extlen > 0) ) { for (i=0;i<mapgrid->extlen;i++) { nbits=abs(mapgrid->ext[i])*8; if ( (mapgrid->ext[i] >= 0) || (igdstmpl[j] >= 0) ) sbit(cgrib,igdstmpl+j,iofst,nbits); else { sbit(cgrib,&one,iofst,1); temp=abs(igdstmpl[j]); sbit(cgrib,&temp,iofst+1,nbits-1); } iofst=iofst+nbits; j++; } } free(mapgrid); // // If requested, // Insert optional list of numbers defining number of points // in each row or column. This is used for non regular // grids. // if ( igds[2] != 0 ) { nbits=igds[2]*8; sbits(cgrib,ideflist,iofst,nbits,0,idefnum); iofst=iofst+(nbits*idefnum); } // // Calculate length of section 3 and store it in octets // 1-4 of section 3. // lensec3=(iofst-ibeg)/8; sbit(cgrib,&lensec3,ibeg,32); // // Update current byte total of message in Section 0 // lencurr+=lensec3; sbit(cgrib,&lencurr,96,32); return(lencurr); } g2clib-1.6.0/g2_addlocal.c0000755002373300042670000001172512522400360015025 0ustar Boi.Vuongglobal#include <stdio.h> #include "grib2.h" g2int g2_addlocal(unsigned char *cgrib,unsigned char *csec2,g2int lcsec2) //$$$ 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, // g2int 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: // //$$$ { g2int ierr; static unsigned char G=0x47; // 'G' static unsigned char R=0x52; // 'R' static unsigned char I=0x49; // 'I' static unsigned char B=0x42; // 'B' static unsigned char seven=0x37; // '7' static g2int two=2; g2int j,k,lensec2,iofst,ibeg,lencurr,ilen,len,istart; g2int isecnum; ierr=0; // // Check to see if beginning of GRIB message exists // if ( cgrib[0]!=G || cgrib[1]!=R || cgrib[2]!=I || cgrib[3]!=B ) { printf("g2_addlocal: GRIB not found in given message.\n"); printf("g2_addlocal: Call to routine g2_create required to initialize GRIB messge.\n"); ierr=-1; return(ierr); } // // Get current length of GRIB message // gbit(cgrib,&lencurr,96,32); // // Check to see if GRIB message is already complete // if ( cgrib[lencurr-4]==seven && cgrib[lencurr-3]==seven && cgrib[lencurr-2]==seven && cgrib[lencurr-1]==seven ) { printf("g2_addlocal: GRIB message already complete. Cannot add new section.\n"); ierr=-2; return(ierr); } // // Loop through all current sections of the GRIB message to // find the last section number. // len=16; // length of Section 0 for (;;) { // Get section number and length of next section iofst=len*8; gbit(cgrib,&ilen,iofst,32); iofst=iofst+32; gbit(cgrib,&isecnum,iofst,8); len=len+ilen; // Exit loop if last section reached if ( len == lencurr ) break; // If byte count for each section doesn't match current // total length, then there is a problem. if ( len > lencurr ) { printf("g2_addlocal: Section byte counts don't add to total.\n"); printf("g2_addlocal: Sum of section byte counts = %ld\n",len); printf("g2_addlocal: Total byte count in Section 0 = %ld\n",lencurr); ierr=-3; return(ierr); } } // // Section 2 can only be added after sections 1 and 7. // if ( (isecnum!=1) && (isecnum!=7) ) { printf("g2_addlocal: Section 2 can only be added after Section 1 or Section 7.\n"); printf("g2_addlocal: Section %ld was the last found in given GRIB message.\n",isecnum); ierr=-4; return(ierr); } // // Add Section 2 - Local Use Section // ibeg=lencurr*8; // Calculate offset for beginning of section 2 iofst=ibeg+32; // leave space for length of section sbit(cgrib,&two,iofst,8); // Store section number ( 2 ) istart=lencurr+5; //cgrib(istart+1:istart+lcsec2)=csec2(1:lcsec2) k=0; for (j=istart;j<istart+lcsec2;j++) { cgrib[j]=csec2[k++]; } // // Calculate length of section 2 and store it in octets // 1-4 of section 2. // lensec2=lcsec2+5; // bytes sbit(cgrib,&lensec2,ibeg,32); // // Update current byte total of message in Section 0 // lencurr+=lensec2; sbit(cgrib,&lencurr,96,32); return(lencurr); } g2clib-1.6.0/g2_create.c0000755002373300042670000001130012522400361014513 0ustar Boi.Vuongglobal#include <stdio.h> #include "grib2.h" #define MAPSEC1LEN 13 g2int g2_create(unsigned char *cgrib,g2int *listsec0,g2int *listsec1) //$$$ 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,g2int *listsec0,g2int *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: // //$$$ { g2int ierr; g2int zero=0,one=1; g2int mapsec1len=MAPSEC1LEN; g2int mapsec1[MAPSEC1LEN]={ 2,2,1,1,1,2,1,1,1,1,1,1,1 }; g2int i,lensec0,lensec1,iofst,ibeg,nbits,len; ierr=0; // // Currently handles only GRIB Edition 2. // if (listsec0[1] != 2) { printf("g2_create: can only code GRIB edition 2."); ierr=-1; return (ierr); } // // Pack Section 0 - Indicator Section // ( except for total length of GRIB message ) // cgrib[0]=0x47; // 'G' // Beginning of GRIB message cgrib[1]=0x52; // 'R' cgrib[2]=0x49; // 'I' cgrib[3]=0x42; // 'B' sbit(cgrib,&zero,32,16); // reserved for future use sbit(cgrib,listsec0+0,48,8); // Discipline sbit(cgrib,listsec0+1,56,8); // GRIB edition number lensec0=16; // bytes (octets) // // Pack Section 1 - Identification Section // ibeg=lensec0*8; // Calculate offset for beginning of section 1 iofst=ibeg+32; // leave space for length of section sbit(cgrib,&one,iofst,8); // Store section number ( 1 ) iofst=iofst+8; // // Pack up 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; sbit(cgrib,listsec1+i,iofst,nbits); iofst=iofst+nbits; } // // Calculate length of section 1 and store it in octets // 1-4 of section 1. // lensec1=(iofst-ibeg)/8; sbit(cgrib,&lensec1,ibeg,32); // // Put current byte total of message into Section 0 // sbit(cgrib,&zero,64,32); len=lensec0+lensec1; sbit(cgrib,&len,96,32); return (len); } g2clib-1.6.0/g2_free.c0000755002373300042670000000245412522400361014203 0ustar Boi.Vuongglobal#include <stdlib.h> #include "grib2.h" void g2_free(gribfield *gfld) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: g2_free // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-28 // // ABSTRACT: This routine frees up memory that was allocated for // struct gribfield. // // PROGRAM HISTORY LOG: // 2002-10-28 Gilbert // // USAGE: g2_free(gribfield *gfld) // ARGUMENT: // gfld - pointer to gribfield structure (defined in include file grib2.h) // returned from routine g2_getfld. // // REMARKS: This routine must be called to free up memory used by // the decode routine, g2_getfld, when user no longer needs to // reference this data. // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$ { if (gfld->idsect != 0 ) free(gfld->idsect); if (gfld->local != 0 ) free(gfld->local); if (gfld->list_opt != 0 ) free(gfld->list_opt); if (gfld->igdtmpl != 0 ) free(gfld->igdtmpl); if (gfld->ipdtmpl != 0 ) free(gfld->ipdtmpl); if (gfld->coord_list != 0 ) free(gfld->coord_list); if (gfld->idrtmpl != 0 ) free(gfld->idrtmpl); if (gfld->bmap != 0 ) free(gfld->bmap); if (gfld->fld != 0 ) free(gfld->fld); free(gfld); return; } g2clib-1.6.0/g2_getfld.c0000755002373300042670000005661612522400361014540 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" g2int g2_unpack1(unsigned char *,g2int *,g2int **,g2int *); g2int g2_unpack2(unsigned char *,g2int *,g2int *,unsigned char **); g2int g2_unpack3(unsigned char *,g2int *,g2int **,g2int **, g2int *,g2int **,g2int *); g2int g2_unpack4(unsigned char *,g2int *,g2int *,g2int **, g2int *,g2float **,g2int *); g2int g2_unpack5(unsigned char *,g2int *,g2int *,g2int *, g2int **,g2int *); g2int g2_unpack6(unsigned char *,g2int *,g2int ,g2int *, g2int **); g2int g2_unpack7(unsigned char *,g2int *,g2int ,g2int *, g2int ,g2int *,g2int ,g2float **); g2int g2_getfld(unsigned char *cgrib,g2int ifldnum,g2int unpack,g2int expand, gribfield **gfld) //$$$ 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 // 2013-08-08 Vuong Free up memory in array igds - free(igds) // // 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 field // 1 = unpack bitmap (if present) 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. // 17 = Previous bitmap specified, yet none exists. // // 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: // //$$$ { g2int have3,have4,have5,have6,have7,ierr,jerr; g2int numfld,j,n,istart,iofst,ipos; g2int disc,ver,lensec0,lengrib,lensec,isecnum; g2int *igds; g2int *bmpsave; g2float *newfld; gribfield *lgfld; have3=0; have4=0; have5=0; have6=0; have7=0; ierr=0; numfld=0; lgfld=(gribfield *)malloc(sizeof(gribfield)); *gfld=lgfld; lgfld->locallen=0; lgfld->idsect=0; lgfld->local=0; lgfld->list_opt=0; lgfld->igdtmpl=0; lgfld->ipdtmpl=0; lgfld->idrtmpl=0; lgfld->coord_list=0; lgfld->bmap=0; lgfld->fld=0; // // Check for valid request number // if (ifldnum <= 0) { printf("g2_getfld: Request for field number must be positive.\n"); ierr=3; return(ierr); } // // 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_getfld: Beginning characters GRIB not found.\n"); ierr=1; return(ierr); } // // Unpack Section 0 - Indicator Section // iofst=8*(istart+6); gbit(cgrib,&disc,iofst,8); // Discipline iofst=iofst+8; gbit(cgrib,&ver,iofst,8); // GRIB edition number iofst=iofst+8; iofst=iofst+32; gbit(cgrib,&lengrib,iofst,32); // Length of GRIB message iofst=iofst+32; lensec0=16; ipos=istart+lensec0; // // Currently handles only GRIB Edition 2. // if (ver != 2) { printf("g2_getfld: can only decode GRIB edition 2.\n"); ierr=2; return(ierr); } // // Loop through the remaining sections keeping track of the // length of each. Also keep the latest Grid Definition Section info. // Unpack the requested field number. // for (;;) { // Check to see if we are at end of GRIB message if (cgrib[ipos]=='7' && cgrib[ipos+1]=='7' && cgrib[ipos+2]=='7' && cgrib[ipos+3]=='7') { ipos=ipos+4; // If end of GRIB message not where expected, issue error if (ipos != (istart+lengrib)) { printf("g2_getfld: '7777' found, but not where expected.\n"); ierr=4; return(ierr); } break; } // Get length of Section and Section number iofst=(ipos-1)*8; 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; //printf(" lensec= %ld secnum= %ld \n",lensec,isecnum); // // Check to see if section number is valid // if ( isecnum<1 || isecnum>7 ) { printf("g2_getfld: Unrecognized Section Encountered=%ld\n",isecnum); ierr=8; return(ierr); } // // If found Section 1, decode elements in Identification Section // if (isecnum == 1) { iofst=iofst-40; // reset offset to beginning of section jerr=g2_unpack1(cgrib,&iofst,&lgfld->idsect,&lgfld->idsectlen); if (jerr !=0 ) { ierr=15; return(ierr); } } // // If found Section 2, Grab local section // Save in case this is the latest one before the requested field. // if (isecnum == 2) { iofst=iofst-40; // reset offset to beginning of section if (lgfld->local!=0) free(lgfld->local); jerr=g2_unpack2(cgrib,&iofst,&lgfld->locallen,&lgfld->local); if (jerr != 0) { ierr=16; return(ierr); } } // // If found Section 3, unpack the GDS info using the // appropriate template. Save in case this is the latest // grid before the requested field. // if (isecnum == 3) { iofst=iofst-40; // reset offset to beginning of section if (lgfld->igdtmpl!=0) free(lgfld->igdtmpl); if (lgfld->list_opt!=0) free(lgfld->list_opt); jerr=g2_unpack3(cgrib,&iofst,&igds,&lgfld->igdtmpl, &lgfld->igdtlen,&lgfld->list_opt,&lgfld->num_opt); if (jerr == 0) { have3=1; lgfld->griddef=igds[0]; lgfld->ngrdpts=igds[1]; lgfld->numoct_opt=igds[2]; lgfld->interp_opt=igds[3]; lgfld->igdtnum=igds[4]; free(igds); } else { ierr=10; return(ierr); } } // // If found Section 4, check to see if this field is the // one requested. // if (isecnum == 4) { numfld=numfld+1; if (numfld == ifldnum) { lgfld->discipline=disc; lgfld->version=ver; lgfld->ifldnum=ifldnum; lgfld->unpacked=unpack; lgfld->expanded=0; iofst=iofst-40; // reset offset to beginning of section jerr=g2_unpack4(cgrib,&iofst,&lgfld->ipdtnum, &lgfld->ipdtmpl,&lgfld->ipdtlen,&lgfld->coord_list, &lgfld->num_coord); if (jerr == 0) have4=1; else { ierr=11; return(ierr); } } } // // If found Section 5, check to see if this field is the // one requested. // if (isecnum == 5 && numfld == ifldnum) { iofst=iofst-40; // reset offset to beginning of section jerr=g2_unpack5(cgrib,&iofst,&lgfld->ndpts,&lgfld->idrtnum, &lgfld->idrtmpl,&lgfld->idrtlen); if (jerr == 0) have5=1; else { ierr=12; return(ierr); } } // // If found Section 6, Unpack bitmap. // Save in case this is the latest // bitmap before the requested field. // if (isecnum == 6) { if (unpack) { // unpack bitmap iofst=iofst-40; // reset offset to beginning of section bmpsave=lgfld->bmap; // save pointer to previous bitmap jerr=g2_unpack6(cgrib,&iofst,lgfld->ngrdpts,&lgfld->ibmap, &lgfld->bmap); if (jerr == 0) { have6=1; if (lgfld->ibmap == 254) // use previously specified bitmap if( bmpsave!=0 ) lgfld->bmap=bmpsave; else { printf("g2_getfld: Prev bit-map specified, but none exist.\n"); ierr=17; return(ierr); } else // get rid of it if( bmpsave!=0 ) free(bmpsave); } else { ierr=13; return(ierr); } } else { // do not unpack bitmap gbit(cgrib,&lgfld->ibmap,iofst,8); // Get BitMap Indicator have6=1; } } // // If found Section 7, check to see if this field is the // one requested. // if (isecnum==7 && numfld==ifldnum && unpack) { iofst=iofst-40; // reset offset to beginning of section jerr=g2_unpack7(cgrib,&iofst,lgfld->igdtnum,lgfld->igdtmpl, lgfld->idrtnum,lgfld->idrtmpl,lgfld->ndpts, &lgfld->fld); if (jerr == 0) { have7=1; // If bitmap is used with this field, expand data field // to grid, if possible. if ( lgfld->ibmap != 255 && lgfld->bmap != 0 ) { if ( expand == 1 ) { n=0; newfld=(g2float *)calloc(lgfld->ngrdpts,sizeof(g2float)); for (j=0;j<lgfld->ngrdpts;j++) { if (lgfld->bmap[j]==1) newfld[j]=lgfld->fld[n++]; } free(lgfld->fld); lgfld->fld=newfld; lgfld->expanded=1; } else { lgfld->expanded=0; } } else { lgfld->expanded=1; } } else { printf("g2_getfld: return from g2_unpack7 = %d \n",(int)jerr); ierr=14; return(ierr); } } // // Check to see if we read pass the end of the GRIB // message and missed the terminator string '7777'. // ipos=ipos+lensec; // Update beginning of section pointer if (ipos > (istart+lengrib)) { printf("g2_getfld: '7777' not found at end of GRIB message.\n"); ierr=7; return(ierr); } // // If unpacking requested, return when all sections have been // processed // if (unpack && have3 && have4 && have5 && have6 && have7) return(ierr); // // If unpacking is not requested, return when sections // 3 through 6 have been processed // if ((! unpack) && have3 && have4 && have5 && have6) return(ierr); } // // If exited from above loop, the end of the GRIB message was reached // before the requested field was found. // printf("g2_getfld: GRIB message contained %ld different fields.\n",numfld); printf("g2_getfld: The request was for field %ld.\n",ifldnum); ierr=6; return(ierr); } g2clib-1.6.0/g2_gribend.c0000755002373300042670000000765512522400361014704 0ustar Boi.Vuongglobal#include <stdio.h> #include "grib2.h" g2int g2_gribend(unsigned char *cgrib) //$$$ 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: // //$$$ { g2int iofst,lencurr,len,ilen,isecnum; g2int ierr,lengrib; static unsigned char G=0x47; // 'G' static unsigned char R=0x52; // 'R' static unsigned char I=0x49; // 'I' static unsigned char B=0x42; // 'B' static unsigned char seven=0x37; // '7' ierr=0; // // Check to see if beginning of GRIB message exists // if ( cgrib[0]!=G || cgrib[1]!=R || cgrib[2]!=I || cgrib[3]!=B ) { printf("g2_gribend: GRIB not found in given message.\n"); ierr=-1; return (ierr); } // // Get current length of GRIB message // gbit(cgrib,&lencurr,96,32); // // Loop through all current sections of the GRIB message to // find the last section number. // len=16; // Length of Section 0 for (;;) { // Get number and length of next section iofst=len*8; gbit(cgrib,&ilen,iofst,32); iofst=iofst+32; gbit(cgrib,&isecnum,iofst,8); len=len+ilen; // Exit loop if last section reached if ( len == lencurr ) break; // If byte count for each section doesn't match current // total length, then there is a problem. if ( len > lencurr ) { printf("g2_gribend: Section byte counts don''t add to total.\n"); printf("g2_gribend: Sum of section byte counts = %d\n",(int)len); printf("g2_gribend: Total byte count in Section 0 = %d\n",(int)lencurr); ierr=-3; return (ierr); } } // // Can only add End Section (Section 8) after Section 7. // if ( isecnum != 7 ) { printf("g2_gribend: Section 8 can only be added after Section 7.\n"); printf("g2_gribend: Section %ld was the last found in given GRIB message.\n",isecnum); ierr=-4; return (ierr); } // // Add Section 8 - End Section // //cgrib(lencurr+1:lencurr+4)=c7777 cgrib[lencurr]=seven; cgrib[lencurr+1]=seven; cgrib[lencurr+2]=seven; cgrib[lencurr+3]=seven; // // Update current byte total of message in Section 0 // lengrib=lencurr+4; sbit(cgrib,&lengrib,96,32); return (lengrib); } g2clib-1.6.0/g2_info.c0000755002373300042670000001503212522400361014211 0ustar Boi.Vuongglobal#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); } g2clib-1.6.0/g2_miss.c0000644002373300042670000000362512522400361014233 0ustar Boi.Vuongglobal#include "grib2.h" void g2_miss( gribfield *gfld, float *rmiss, int *nmiss ) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: g2_miss // PRGMMR: Gilbert ORG: W/NP11 DATE: 2004-12-16 // // ABSTRACT: This routine checks the Data Representation Template to see if // missing value management is used, and returns the missing value(s) // in the data field. // // PROGRAM HISTORY LOG: // 2004-12-16 Gilbert // // USAGE: g2_miss( gribfield *gfld, float *rmiss, int *nmiss ) // // INPUT ARGUMENT LIST: // *gfld - pointer to gribfield structure (defined in include file // grib2.h) // // OUTPUT ARGUMENT LIST: // rmiss - List of the missing values used // nmiss - NUmber of the missing values included in the field // // REMARKS: rmiss must be allocated in the calling program with enough space // hold all the missing values. // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { g2int itype; /* * Missing value management currnetly only used in * DRT's 5.2 and 5.3. */ if ( gfld->idrtnum != 2 && gfld->idrtnum != 3 ) { *nmiss=0; return; } itype = gfld->idrtmpl[4]; if ( gfld->idrtmpl[6] == 1 ) { *nmiss=1; if (itype == 0) rdieee(gfld->idrtmpl+7,rmiss+0,1); else rmiss[0]=(float)gfld->idrtmpl[7]; } else if ( gfld->idrtmpl[6] == 2 ) { *nmiss=2; if (itype == 0) { rdieee(gfld->idrtmpl+7,rmiss+0,1); rdieee(gfld->idrtmpl+8,rmiss+1,1); } else { rmiss[0]=(float)gfld->idrtmpl[7]; rmiss[1]=(float)gfld->idrtmpl[8]; } } else { *nmiss=0; } } g2clib-1.6.0/g2_unpack1.c0000755002373300042670000000623112522400361014621 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" g2int g2_unpack1(unsigned char *cgrib,g2int *iofst,g2int **ids,g2int *idslen) /*//$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: g2_unpack1 // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-29 // // ABSTRACT: This subroutine unpacks Section 1 (Identification Section) // as defined in GRIB Edition 2. // // PROGRAM HISTORY LOG: // 2002-10-29 Gilbert // // USAGE: int g2_unpack1(unsigned char *cgrib,g2int *iofst,g2int **ids, // g2int *idslen) // INPUT ARGUMENTS: // cgrib - char array containing Section 1 of the GRIB2 message // iofst - Bit offset for the beginning of Section 1 in cgrib. // // OUTPUT ARGUMENTS: // iofst - Bit offset at the end of Section 1, returned. // ids - address of pointer to integer array containing information // read from Section 1, the Identification section. // ids[0] = Identification of originating Centre // ( see Common Code Table C-1 ) // ids[1] = Identification of originating Sub-centre // ids[2] = GRIB Master Tables Version Number // ( see Code Table 1.0 ) // ids[3] = GRIB Local Tables Version Number // ( see Code Table 1.1 ) // ids[4] = Significance of Reference Time (Code Table 1.2) // ids[5] = Year ( 4 digits ) // ids[6] = Month // ids[7] = Day // ids[8] = Hour // ids[9] = Minute // ids[10] = Second // ids[11] = Production status of processed data // ( see Code Table 1.3 ) // ids[12] = Type of processed data ( see Code Table 1.4 ) // idslen - Number of elements in ids[]. // // RETURN VALUES: // ierr - Error return code. // 0 = no error // 2 = Array passed is not section 1 // 6 = memory allocation error // // REMARKS: // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$ */ { g2int i,lensec,nbits,ierr,isecnum; g2int mapid[13]={2,2,1,1,1,2,1,1,1,1,1,1,1}; ierr=0; *idslen=13; *ids=0; gbit(cgrib,&lensec,*iofst,32); // Get Length of Section *iofst=*iofst+32; gbit(cgrib,&isecnum,*iofst,8); // Get Section Number *iofst=*iofst+8; if ( isecnum != 1 ) { ierr=2; *idslen=13; fprintf(stderr,"g2_unpack1: Not Section 1 data.\n"); return(ierr); } // // Unpack each value into array ids from the // the appropriate number of octets, which are specified in // corresponding entries in array mapid. // *ids=(g2int *)calloc(*idslen,sizeof(g2int)); if (*ids == 0) { ierr=6; return(ierr); } for (i=0;i<*idslen;i++) { nbits=mapid[i]*8; gbit(cgrib,*ids+i,*iofst,nbits); *iofst=*iofst+nbits; } return(ierr); // End of Section 1 processing } g2clib-1.6.0/g2_unpack2.c0000755002373300042670000000454012522400361014623 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" g2int g2_unpack2(unsigned char *cgrib,g2int *iofst,g2int *lencsec2,unsigned char **csec2) ////$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: g2_unpack2 // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-31 // // ABSTRACT: This subroutine unpacks Section 2 (Local Use Section) // as defined in GRIB Edition 2. // // PROGRAM HISTORY LOG: // 2002-10-31 Gilbert // 2008-12-23 Wesley - Initialize lencsec2 Length of Local Use data // 2010-08-05 Vuong - If section 2 has zero length, ierr=0 // // USAGE: int g2_unpack2(unsigned char *cgrib,g2int *iofst,g2int *lencsec2, // unsigned char **csec2) // INPUT ARGUMENT LIST: // cgrib - char array containing Section 2 of the GRIB2 message // iofst - Bit offset for the beginning of Section 2 in cgrib. // // OUTPUT ARGUMENT LIST: // iofst - Bit offset at the end of Section 2, returned. // lencsec2 - Length (in octets) of Local Use data // csec2 - Pointer to a char array containing local use data // // RETURN VALUES: // ierr - Error return code. // 0 = no error // 2 = Array passed is not section 2 // 6 = memory allocation error // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$// { g2int ierr,isecnum; g2int lensec,ipos,j; ierr=0; *lencsec2=0; *csec2=0; // NULL gbit(cgrib,&lensec,*iofst,32); // Get Length of Section *iofst=*iofst+32; *lencsec2=lensec-5; gbit(cgrib,&isecnum,*iofst,8); // Get Section Number *iofst=*iofst+8; ipos=(*iofst/8); if ( isecnum != 2 ) { ierr=2; *lencsec2=0; fprintf(stderr,"g2_unpack2: Not Section 2 data.\n"); return(ierr); } if (*lencsec2 == 0) { ierr = 0; return(ierr); } *csec2=(unsigned char *)malloc(*lencsec2+1); if (*csec2 == 0) { ierr=6; *lencsec2=0; return(ierr); } //printf(" SAGIPO %d \n",(int)ipos); for (j=0;j<*lencsec2;j++) { *(*csec2+j)=cgrib[ipos+j]; } *iofst=*iofst+(*lencsec2*8); return(ierr); // End of Section 2 processing } g2clib-1.6.0/g2_unpack3.c0000755002373300042670000001726212522400361014631 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" g2int g2_unpack3(unsigned char *cgrib,g2int *iofst,g2int **igds,g2int **igdstmpl, g2int *mapgridlen,g2int **ideflist,g2int *idefnum) ////$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: g2_unpack3 // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-31 // // ABSTRACT: This routine unpacks Section 3 (Grid Definition Section) // as defined in GRIB Edition 2. // // PROGRAM HISTORY LOG: // 2002-10-31 Gilbert // 2009-01-14 Vuong Changed structure name template to gtemplate // // USAGE: int g2_unpack3(unsigned char *cgrib,g2int *iofst,g2int **igds, // g2int **igdstmpl,g2int *mapgridlen, // g2int **ideflist,g2int *idefnum) // INPUT ARGUMENTS: // cgrib - Char array ontaining Section 3 of the GRIB2 message // iofst - Bit offset for the beginning of Section 3 in cgrib. // // OUTPUT ARGUMENTS: // iofst - Bit offset at the end of Section 3, returned. // igds - Contains information read from the appropriate GRIB Grid // Definition Section 3 for the field being returned. // 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 - Pointer to integer array containing 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 // mapgridlen- Number of elements in igdstmpl[]. i.e. number of entries // in Grid Defintion Template 3.NN ( NN=igds[4] ). // ideflist - (Used if igds[2] .ne. 0) Pointer to integer array containing // the number of grid points contained in each row ( or column ). // (part of Section 3) // idefnum - (Used if igds[2] .ne. 0) The number of entries // in array ideflist. i.e. number of rows ( or columns ) // for which optional grid points are defined. // ierr - Error return code. // 0 = no error // 2 = Not Section 3 // 5 = "GRIB" message contains an undefined Grid Definition // Template. // 6 = memory allocation error // // REMARKS: // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$ { g2int ierr,i,j,nbits,isecnum; g2int lensec,ibyttem=0,isign,newlen; g2int *ligds,*ligdstmpl=0,*lideflist=0; gtemplate *mapgrid; ierr=0; *igds=0; // NULL *igdstmpl=0; // NULL *ideflist=0; // NULL gbit(cgrib,&lensec,*iofst,32); // Get Length of Section *iofst=*iofst+32; gbit(cgrib,&isecnum,*iofst,8); // Get Section Number *iofst=*iofst+8; if ( isecnum != 3 ) { ierr=2; *idefnum=0; *mapgridlen=0; // fprintf(stderr,"g2_unpack3: Not Section 3 data.\n"); return(ierr); } ligds=(g2int *)calloc(5,sizeof(g2int)); *igds=ligds; gbit(cgrib,ligds+0,*iofst,8); // Get source of Grid def. *iofst=*iofst+8; gbit(cgrib,ligds+1,*iofst,32); // Get number of grid pts. *iofst=*iofst+32; gbit(cgrib,ligds+2,*iofst,8); // Get num octets for opt. list *iofst=*iofst+8; gbit(cgrib,ligds+3,*iofst,8); // Get interpret. for opt. list *iofst=*iofst+8; gbit(cgrib,ligds+4,*iofst,16); // Get Grid Def Template num. *iofst=*iofst+16; if (ligds[4] != 65535) { // Get Grid Definition Template mapgrid=getgridtemplate(ligds[4]); if (mapgrid == 0) { // undefined template ierr=5; return(ierr); } *mapgridlen=mapgrid->maplen; // // Unpack each value into array igdstmpl from the // the appropriate number of octets, which are specified in // corresponding entries in array mapgrid. // if (*mapgridlen > 0) { ligdstmpl=0; ligdstmpl=(g2int *)calloc(*mapgridlen,sizeof(g2int)); if (ligdstmpl == 0) { ierr=6; *mapgridlen=0; *igdstmpl=0; //NULL if( mapgrid != 0 ) free(mapgrid); return(ierr); } else { *igdstmpl=ligdstmpl; } } ibyttem=0; for (i=0;i<*mapgridlen;i++) { nbits=abs(mapgrid->map[i])*8; if ( mapgrid->map[i] >= 0 ) { gbit(cgrib,ligdstmpl+i,*iofst,nbits); } else { gbit(cgrib,&isign,*iofst,1); gbit(cgrib,ligdstmpl+i,*iofst+1,nbits-1); if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i]; } *iofst=*iofst+nbits; ibyttem=ibyttem+abs(mapgrid->map[i]); } // // Check to see if the Grid Definition Template needs to be // extended. // The number of values in a specific template may vary // depending on data specified in the "static" part of the // gtemplate. // if ( mapgrid->needext == 1 ) { free(mapgrid); mapgrid=extgridtemplate(ligds[4],ligdstmpl); // Unpack the rest of the Grid Definition Template newlen=mapgrid->maplen+mapgrid->extlen; ligdstmpl=(g2int *)realloc(ligdstmpl,newlen*sizeof(g2int)); *igdstmpl=ligdstmpl; j=0; for (i=*mapgridlen;i<newlen;i++) { nbits=abs(mapgrid->ext[j])*8; if ( mapgrid->ext[j] >= 0 ) { gbit(cgrib,ligdstmpl+i,*iofst,nbits); } else { gbit(cgrib,&isign,*iofst,1); gbit(cgrib,ligdstmpl+i,*iofst+1,nbits-1); if (isign == 1) ligdstmpl[i]=-1*ligdstmpl[i]; } *iofst=*iofst+nbits; ibyttem=ibyttem+abs(mapgrid->ext[j]); j++; } *mapgridlen=newlen; } if( mapgrid->ext != 0 ) free(mapgrid->ext); if( mapgrid != 0 ) free(mapgrid); } else { // No Grid Definition Template *mapgridlen=0; *igdstmpl=0; } // // Unpack optional list of numbers defining number of points // in each row or column, if included. This is used for non regular // grids. // if ( ligds[2] != 0 ) { nbits=ligds[2]*8; *idefnum=(lensec-14-ibyttem)/ligds[2]; if (*idefnum > 0) lideflist=(g2int *)calloc(*idefnum,sizeof(g2int)); if (lideflist == 0) { ierr=6; *idefnum=0; *ideflist=0; //NULL return(ierr); } else { *ideflist=lideflist; } gbits(cgrib,lideflist,*iofst,nbits,0,*idefnum); *iofst=*iofst+(nbits*(*idefnum)); } else { *idefnum=0; *ideflist=0; // NULL } return(ierr); // End of Section 3 processing } g2clib-1.6.0/g2_unpack4.c0000755002373300042670000001427112522400361014627 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" g2int g2_unpack4(unsigned char *cgrib,g2int *iofst,g2int *ipdsnum,g2int **ipdstmpl, g2int *mappdslen,g2float **coordlist,g2int *numcoord) ////$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: g2_unpack4 // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-31 // // ABSTRACT: This subroutine unpacks Section 4 (Product Definition Section) // as defined in GRIB Edition 2. // // PROGRAM HISTORY LOG: // 2002-10-31 Gilbert // 2009-01-14 Vuong Changed structure name template to gtemplate // // USAGE: int g2_unpack4(unsigned char *cgrib,g2int *iofst,g2int *ipdsnum, // g2int **ipdstmpl,g2int *mappdslen, // g2float **coordlist,g2int *numcoord) // INPUT ARGUMENTS: // cgrib - Char array containing Section 4 of the GRIB2 message // iofst - Bit offset of the beginning of Section 4 in cgrib. // // OUTPUT ARGUMENTS: // iofst - Bit offset of the end of Section 4, returned. // ipdsnum - Product Definition Template Number ( see Code Table 4.0) // ipdstmpl - Pointer to integer array containing 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 // mappdslen- Number of elements in ipdstmpl[]. i.e. number of entries // in Product Defintion Template 4.N ( N=ipdsnum ). // coordlist- Pointer to 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) // numcoord - number of values in array coordlist. // // RETURN VALUES: // ierr - Error return code. // 0 = no error // 2 = Not section 4 // 5 = "GRIB" message contains an undefined Product Definition // Template. // 6 = memory allocation error // // REMARKS: // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$// { g2int ierr,needext,i,j,nbits,isecnum; g2int lensec,isign,newlen; g2int *coordieee; g2int *lipdstmpl=0; g2float *lcoordlist; gtemplate *mappds; ierr=0; *ipdstmpl=0; // NULL *coordlist=0; // NULL gbit(cgrib,&lensec,*iofst,32); // Get Length of Section *iofst=*iofst+32; gbit(cgrib,&isecnum,*iofst,8); // Get Section Number *iofst=*iofst+8; if ( isecnum != 4 ) { ierr=2; *numcoord=0; *mappdslen=0; // fprintf(stderr,"g2_unpack4: Not Section 4 data.\n"); return(ierr); } gbit(cgrib,numcoord,*iofst,16); // Get num of coordinate values *iofst=*iofst+16; gbit(cgrib,ipdsnum,*iofst,16); // Get Prod. Def Template num. *iofst=*iofst+16; // Get Product Definition Template mappds=getpdstemplate(*ipdsnum); if (mappds == 0) { // undefine template ierr=5; *mappdslen=0; return(ierr); } *mappdslen=mappds->maplen; needext=mappds->needext; // // Unpack each value into array ipdstmpl from the // the appropriate number of octets, which are specified in // corresponding entries in array mappds. // if (*mappdslen > 0) lipdstmpl=(g2int *)calloc(*mappdslen,sizeof(g2int)); if (lipdstmpl == 0) { ierr=6; *mappdslen=0; *ipdstmpl=0; //NULL if ( mappds != 0 ) free(mappds); return(ierr); } else { *ipdstmpl=lipdstmpl; } for (i=0;i<mappds->maplen;i++) { nbits=abs(mappds->map[i])*8; if ( mappds->map[i] >= 0 ) { gbit(cgrib,lipdstmpl+i,*iofst,nbits); } else { gbit(cgrib,&isign,*iofst,1); gbit(cgrib,lipdstmpl+i,*iofst+1,nbits-1); if (isign == 1) lipdstmpl[i]=-1*lipdstmpl[i]; } *iofst=*iofst+nbits; } // // Check to see if the Product Definition Template needs to be // extended. // The number of values in a specific template may vary // depending on data specified in the "static" part of the // gtemplate. // if ( needext ==1 ) { free(mappds); mappds=extpdstemplate(*ipdsnum,lipdstmpl); newlen=mappds->maplen+mappds->extlen; lipdstmpl=(g2int *)realloc(lipdstmpl,newlen*sizeof(g2int)); *ipdstmpl=lipdstmpl; // Unpack the rest of the Product Definition Template j=0; for (i=*mappdslen;i<newlen;i++) { nbits=abs(mappds->ext[j])*8; if ( mappds->ext[j] >= 0 ) { gbit(cgrib,lipdstmpl+i,*iofst,nbits); } else { gbit(cgrib,&isign,*iofst,1); gbit(cgrib,lipdstmpl+i,*iofst+1,nbits-1); if (isign == 1) lipdstmpl[i]=-1*lipdstmpl[i]; } *iofst=*iofst+nbits; j++; } *mappdslen=newlen; } if( mappds->ext != 0 ) free(mappds->ext); if( mappds != 0 ) free(mappds); // // Get Optional list of vertical coordinate values // after the Product Definition Template, if necessary. // *coordlist=0; // NULL if ( *numcoord != 0 ) { coordieee=(g2int *)calloc(*numcoord,sizeof(g2int)); lcoordlist=(g2float *)calloc(*numcoord,sizeof(g2float)); if (coordieee == 0 || lcoordlist == 0) { ierr=6; *numcoord=0; *coordlist=0; // NULL if( coordieee != 0 ) free(coordieee); if( lcoordlist != 0 ) free(lcoordlist); return(ierr); } else { *coordlist=lcoordlist; } gbits(cgrib,coordieee,*iofst,32,0,*numcoord); rdieee(coordieee,*coordlist,*numcoord); free(coordieee); *iofst=*iofst+(32*(*numcoord)); } return(ierr); // End of Section 4 processing } g2clib-1.6.0/g2_unpack5.c0000755002373300042670000001170312522400361014625 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" g2int g2_unpack5(unsigned char *cgrib,g2int *iofst,g2int *ndpts,g2int *idrsnum, g2int **idrstmpl,g2int *mapdrslen) ////$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: g2_unpack5 // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-31 // // ABSTRACT: This subroutine unpacks Section 5 (Data Representation Section) // as defined in GRIB Edition 2. // // PROGRAM HISTORY LOG: // 2002-10-31 Gilbert // 2009-01-14 Vuong Changed structure name template to gtemplate // // USAGE: int g2_unpack5(unsigned char *cgrib,g2int *iofst,g2int *ndpts, // g2int *idrsnum,g2int **idrstmpl,g2int *mapdrslen) // INPUT ARGUMENTS: // cgrib - char array containing Section 5 of the GRIB2 message // iofst - Bit offset for the beginning of Section 5 in cgrib. // // OUTPUT ARGUMENTS: // iofst - Bit offset at the end of Section 5, returned. // ndpts - Number of data points unpacked and returned. // idrsnum - Data Representation Template Number ( see Code Table 5.0) // idrstmpl - Pointer to an integer array containing 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 // mapdrslen- Number of elements in idrstmpl[]. i.e. number of entries // in Data Representation Template 5.N ( N=idrsnum ). // // RETURN VALUES: // ierr - Error return code. // 0 = no error // 2 = Not Section 5 // 6 = memory allocation error // 7 = "GRIB" message contains an undefined Data // Representation Template. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$// { g2int ierr,needext,i,j,nbits,isecnum; g2int lensec,isign,newlen; g2int *lidrstmpl=0; gtemplate *mapdrs; ierr=0; *idrstmpl=0; //NULL gbit(cgrib,&lensec,*iofst,32); // Get Length of Section *iofst=*iofst+32; gbit(cgrib,&isecnum,*iofst,8); // Get Section Number *iofst=*iofst+8; if ( isecnum != 5 ) { ierr=2; *ndpts=0; *mapdrslen=0; // fprintf(stderr,"g2_unpack5: Not Section 5 data.\n"); return(ierr); } gbit(cgrib,ndpts,*iofst,32); // Get num of data points *iofst=*iofst+32; gbit(cgrib,idrsnum,*iofst,16); // Get Data Rep Template Num. *iofst=*iofst+16; // Gen Data Representation Template mapdrs=getdrstemplate(*idrsnum); if (mapdrs == 0) { ierr=7; *mapdrslen=0; return(ierr); } *mapdrslen=mapdrs->maplen; needext=mapdrs->needext; // // Unpack each value into array ipdstmpl from the // the appropriate number of octets, which are specified in // corresponding entries in array mapdrs. // if (*mapdrslen > 0) lidrstmpl=(g2int *)calloc(*mapdrslen,sizeof(g2int)); if (lidrstmpl == 0) { ierr=6; *mapdrslen=0; *idrstmpl=0; //NULL if ( mapdrs != 0 ) free(mapdrs); return(ierr); } else { *idrstmpl=lidrstmpl; } for (i=0;i<mapdrs->maplen;i++) { nbits=abs(mapdrs->map[i])*8; if ( mapdrs->map[i] >= 0 ) { gbit(cgrib,lidrstmpl+i,*iofst,nbits); } else { gbit(cgrib,&isign,*iofst,1); gbit(cgrib,lidrstmpl+i,*iofst+1,nbits-1); if (isign == 1) lidrstmpl[i]=-1*lidrstmpl[i]; } *iofst=*iofst+nbits; } // // Check to see if the Data Representation Template needs to be // extended. // The number of values in a specific gtemplate may vary // depending on data specified in the "static" part of the // gtemplate. // if ( needext == 1 ) { free(mapdrs); mapdrs=extdrstemplate(*idrsnum,lidrstmpl); newlen=mapdrs->maplen+mapdrs->extlen; lidrstmpl=(g2int *)realloc(lidrstmpl,newlen*sizeof(g2int)); *idrstmpl=lidrstmpl; // Unpack the rest of the Data Representation Template j=0; for (i=*mapdrslen;i<newlen;i++) { nbits=abs(mapdrs->ext[j])*8; if ( mapdrs->ext[j] >= 0 ) { gbit(cgrib,lidrstmpl+i,*iofst,nbits); } else { gbit(cgrib,&isign,*iofst,1); gbit(cgrib,lidrstmpl+i,*iofst+1,nbits-1); if (isign == 1) lidrstmpl[i]=-1*lidrstmpl[i]; } *iofst=*iofst+nbits; j++; } *mapdrslen=newlen; } if( mapdrs->ext != 0 ) free(mapdrs->ext); if( mapdrs != 0 ) free(mapdrs); return(ierr); // End of Section 5 processing } g2clib-1.6.0/g2_unpack6.c0000755002373300042670000000600112522400361014621 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" g2int g2_unpack6(unsigned char *cgrib,g2int *iofst,g2int ngpts,g2int *ibmap, g2int **bmap) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: g2_unpack6 // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-31 // // ABSTRACT: This subroutine unpacks Section 6 (Bit-Map Section) // as defined in GRIB Edition 2. // // PROGRAM HISTORY LOG: // 2002-10-31 Gilbert // // USAGE: int g2_unpack6(unsigned char *cgrib,g2int *iofst,g2int ngpts, // g2int *ibmap,g2int **bmap) // INPUT ARGUMENTS: // cgrib - char array containing Section 6 of the GRIB2 message // iofst - Bit offset of the beginning of Section 6 in cgrib. // ngpts - Number of grid points specified in the bit-map // // OUTPUT ARGUMENTS: // iofst - Bit offset at the end of Section 6, returned. // 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 - Pointer to an integer array containing decoded bitmap. // ( if ibmap=0 ) // // RETURN VALUES: // ierr - Error return code. // 0 = no error // 2 = Not Section 6 // 4 = Unrecognized pre-defined bit-map. // 6 = memory allocation error // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$// { g2int j,ierr,isecnum; g2int *lbmap=0; g2int *intbmap; ierr=0; *bmap=0; //NULL *iofst=*iofst+32; // skip Length of Section gbit(cgrib,&isecnum,*iofst,8); // Get Section Number *iofst=*iofst+8; if ( isecnum != 6 ) { ierr=2; fprintf(stderr,"g2_unpack6: Not Section 6 data.\n"); return(ierr); } gbit(cgrib,ibmap,*iofst,8); // Get bit-map indicator *iofst=*iofst+8; if (*ibmap == 0) { // Unpack bitmap if (ngpts > 0) lbmap=(g2int *)calloc(ngpts,sizeof(g2int)); if (lbmap == 0) { ierr=6; return(ierr); } else { *bmap=lbmap; } intbmap=(g2int *)calloc(ngpts,sizeof(g2int)); gbits(cgrib,intbmap,*iofst,1,0,ngpts); *iofst=*iofst+ngpts; for (j=0;j<ngpts;j++) { lbmap[j]=(g2int)intbmap[j]; } free(intbmap); // else if (*ibmap.eq.254) ! Use previous bitmap // return(ierr); // else if (*ibmap.eq.255) ! No bitmap in message // bmap(1:ngpts)=.true. // else { // print *,'gf_unpack6: Predefined bitmap ',*ibmap,' not recognized.' // ierr=4; } return(ierr); // End of Section 6 processing } g2clib-1.6.0/g2_unpack7.c0000755002373300042670000001277312522400361014637 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <string.h> #include "grib2.h" g2int simunpack(unsigned char *,g2int *, g2int,g2float *); int comunpack(unsigned char *,g2int,g2int,g2int *,g2int,g2float *); g2int specunpack(unsigned char *,g2int *,g2int,g2int,g2int, g2int, g2float *); #ifdef USE_PNG g2int pngunpack(unsigned char *,g2int,g2int *,g2int, g2float *); #endif /* USE_PNG */ #ifdef USE_JPEG2000 g2int jpcunpack(unsigned char *,g2int,g2int *,g2int, g2float *); #endif /* USE_JPEG2000 */ g2int g2_unpack7(unsigned char *cgrib,g2int *iofst,g2int igdsnum,g2int *igdstmpl, g2int idrsnum,g2int *idrstmpl,g2int ndpts,g2float **fld) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: g2_unpack7 // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-31 // // ABSTRACT: This subroutine unpacks Section 7 (Data Section) // as defined in GRIB Edition 2. // // PROGRAM HISTORY LOG: // 2002-10-31 Gilbert // 2002-12-20 Gilbert - Added GDT info to arguments // and added 5.51 processing. // 2003-08-29 Gilbert - Added support for new templates using // PNG and JPEG2000 algorithms/templates. // 2004-11-29 Gilbert - JPEG2000 now allowed to use WMO Template no. 5.40 // PNG now allowed to use WMO Template no. 5.41 // 2004-12-16 Taylor - Added check on comunpack return code. // 2008-12-23 Wesley - Initialize Number of data points unpacked // // USAGE: int g2_unpack7(unsigned char *cgrib,g2int *iofst,g2int igdsnum, // g2int *igdstmpl, g2int idrsnum, // g2int *idrstmpl, g2int ndpts,g2float **fld) // INPUT ARGUMENTS: // cgrib - char array containing Section 7 of the GRIB2 message // iofst - Bit offset of the beginning of Section 7 in cgrib. // igdsnum - Grid Definition Template Number ( see Code Table 3.0) // ( Only used for DRS Template 5.51 ) // igdstmpl - Pointer to an integer array containing the data values for // the specified Grid Definition // Template ( N=igdsnum ). Each element of this integer // array contains an entry (in the order specified) of Grid // Definition Template 3.N // ( Only used for DRS Template 5.51 ) // idrsnum - Data Representation Template Number ( see Code Table 5.0) // idrstmpl - Pointer to an integer array containing 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 // ndpts - Number of data points unpacked and returned. // // OUTPUT ARGUMENTS: // iofst - Bit offset at the end of Section 7, returned. // fld - Pointer to a float array containing the unpacked data field. // // RETURN VALUES: // ierr - Error return code. // 0 = no error // 2 = Not section 7 // 4 = Unrecognized Data Representation Template // 5 = need one of GDT 3.50 through 3.53 to decode DRT 5.51 // 6 = memory allocation error // 7 = corrupt section 7. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$// { g2int ierr,isecnum; g2int ipos,lensec; g2float *lfld; ierr=0; *fld=0; //NULL gbit(cgrib,&lensec,*iofst,32); // Get Length of Section *iofst=*iofst+32; gbit(cgrib,&isecnum,*iofst,8); // Get Section Number *iofst=*iofst+8; if ( isecnum != 7 ) { ierr=2; //fprintf(stderr,"g2_unpack7: Not Section 7 data.\n"); return(ierr); } ipos=(*iofst/8); lfld=(g2float *)calloc(ndpts ? ndpts : 1,sizeof(g2float)); if (lfld == 0) { ierr=6; return(ierr); } else { *fld=lfld; } if (idrsnum == 0) simunpack(cgrib+ipos,idrstmpl,ndpts,lfld); else if (idrsnum == 2 || idrsnum == 3) { if (comunpack(cgrib+ipos,lensec,idrsnum,idrstmpl,ndpts,lfld) != 0) { return 7; } } else if (idrsnum == 50) { // Spectral Simple simunpack(cgrib+ipos,idrstmpl,ndpts-1,lfld+1); rdieee(idrstmpl+4,lfld+0,1); } else if (idrsnum == 51) // Spectral complex if ( igdsnum>=50 && igdsnum <=53 ) specunpack(cgrib+ipos,idrstmpl,ndpts,igdstmpl[0],igdstmpl[2],igdstmpl[2],lfld); else { fprintf(stderr,"g2_unpack7: Cannot use GDT 3.%d to unpack Data Section 5.51.\n",(int)igdsnum); ierr=5; if ( lfld != 0 ) free(lfld); *fld=0; //NULL return(ierr); } #ifdef USE_JPEG2000 else if (idrsnum == 40 || idrsnum == 40000) { jpcunpack(cgrib+ipos,lensec-5,idrstmpl,ndpts,lfld); } #endif /* USE_JPEG2000 */ #ifdef USE_PNG else if (idrsnum == 41 || idrsnum == 40010) { pngunpack(cgrib+ipos,lensec-5,idrstmpl,ndpts,lfld); } #endif /* USE_PNG */ else { fprintf(stderr,"g2_unpack7: Data Representation Template 5.%d not yet implemented.\n",(int)idrsnum); ierr=4; if ( lfld != 0 ) free(lfld); *fld=0; //NULL return(ierr); } *iofst=*iofst+(8*lensec); return(ierr); // End of Section 7 processing } g2clib-1.6.0/gbits.c0000755002373300042670000000725012522400361014001 0ustar Boi.Vuongglobal#include "grib2.h" void gbit(unsigned char *in,g2int *iout,g2int iskip,g2int nbyte) { gbits(in,iout,iskip,nbyte,(g2int)0,(g2int)1); } void sbit(unsigned char *out,g2int *in,g2int iskip,g2int nbyte) { sbits(out,in,iskip,nbyte,(g2int)0,(g2int)1); } void gbits(unsigned char *in,g2int *iout,g2int iskip,g2int nbyte,g2int nskip, g2int n) /* Get bits - unpack bits: Extract arbitrary size values from a / packed bit string, right justifying each value in the unpacked / iout array. / *in = pointer to character array input / *iout = pointer to unpacked array output / iskip = initial number of bits to skip / nbyte = number of bits to take / nskip = additional number of bits to skip on each iteration / n = number of iterations / v1.1 */ { g2int i,tbit,bitcnt,ibit,itmp; g2int nbit,index; static g2int ones[]={1,3,7,15,31,63,127,255}; // nbit is the start position of the field in bits nbit = iskip; for (i=0;i<n;i++) { bitcnt = nbyte; index=nbit/8; ibit=nbit%8; nbit = nbit + nbyte + nskip; // first byte tbit= ( bitcnt < (8-ibit) ) ? bitcnt : 8-ibit; // find min itmp = (int)*(in+index) & ones[7-ibit]; if (tbit != 8-ibit) itmp >>= (8-ibit-tbit); index++; bitcnt = bitcnt - tbit; // now transfer whole bytes while (bitcnt >= 8) { itmp = itmp<<8 | (int)*(in+index); bitcnt = bitcnt - 8; index++; } // get data from last byte if (bitcnt > 0) { itmp = ( itmp << bitcnt ) | ( ((int)*(in+index) >> (8-bitcnt)) & ones[bitcnt-1] ); } *(iout+i) = itmp; } } void sbits(unsigned char *out,g2int *in,g2int iskip,g2int nbyte,g2int nskip, g2int n) /*C Store bits - pack bits: Put arbitrary size values into a / packed bit string, taking the low order bits from each value / in the unpacked array. / *iout = pointer to packed array output / *in = pointer to unpacked array input / iskip = initial number of bits to skip / nbyte = number of bits to pack / nskip = additional number of bits to skip on each iteration / n = number of iterations / v1.1 */ { g2int i,bitcnt,tbit,ibit,itmp,imask,itmp2,itmp3; g2int nbit,index; static g2int ones[]={1,3,7,15,31,63,127,255}; // number bits from zero to ... // nbit is the last bit of the field to be filled nbit = iskip + nbyte - 1; for (i=0;i<n;i++) { itmp = *(in+i); bitcnt = nbyte; index=nbit/8; ibit=nbit%8; nbit = nbit + nbyte + nskip; // make byte aligned if (ibit != 7) { tbit= ( bitcnt < (ibit+1) ) ? bitcnt : ibit+1; // find min imask = ones[tbit-1] << (7-ibit); itmp2 = (itmp << (7-ibit)) & imask; itmp3 = (int)*(out+index) & (255-imask); out[index] = (unsigned char)(itmp2 | itmp3); bitcnt = bitcnt - tbit; itmp = itmp >> tbit; index--; } // now byte aligned // do by bytes while (bitcnt >= 8) { out[index] = (unsigned char)(itmp & 255); itmp = itmp >> 8; bitcnt = bitcnt - 8; index--; } // do last byte if (bitcnt > 0) { itmp2 = itmp & ones[bitcnt-1]; itmp3 = (int)*(out+index) & (255-ones[bitcnt-1]); out[index] = (unsigned char)(itmp2 | itmp3); } } } g2clib-1.6.0/getdim.c0000644002373300042670000000656312522400361014145 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" g2int g2_unpack3(unsigned char *,g2int *,g2int **,g2int **, g2int *,g2int **,g2int *); g2int getdim(unsigned char *csec3,g2int *width,g2int *height,g2int *iscan) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: getdim // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-11 // // ABSTRACT: This subroutine returns the dimensions and scanning mode of // a grid definition packed in GRIB2 Grid Definition Section 3 format. // // PROGRAM HISTORY LOG: // 2002-12-11 Gilbert // // USAGE: int getdim(unsigned char *csec3,g2int *width, // g2int *height, g2int *iscan) // INPUT ARGUMENT LIST: // csec3 - Character array that contains the packed GRIB2 GDS // // OUTPUT ARGUMENT LIST: // width - x (or i) dimension of the grid. // height - y (or j) dimension of the grid. // iscan - Scanning mode ( see Code Table 3.4 ) // // REMARKS: Returns width and height set to zero, if grid template // not recognized. // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { g2int *igdstmpl,*list_opt; g2int *igds; g2int iofst,igdtlen,num_opt,jerr; igdstmpl=0; list_opt=0; igds=0; iofst=0; // set offset to beginning of section jerr= g2_unpack3(csec3,&iofst,&igds,&igdstmpl, &igdtlen,&list_opt,&num_opt); if (jerr == 0) { switch ( igds[4] ) // Template number { case 0: // Lat/Lon case 1: case 2: case 3: { *width=igdstmpl[7]; *height=igdstmpl[8]; *iscan=igdstmpl[18]; break; } case 10: // Mercator { *width=igdstmpl[7]; *height=igdstmpl[8]; *iscan=igdstmpl[15]; break; } case 20: // Polar Stereographic { *width=igdstmpl[7]; *height=igdstmpl[8]; *iscan=igdstmpl[17]; break; } case 30: // Lambert Conformal { *width=igdstmpl[7]; *height=igdstmpl[8]; *iscan=igdstmpl[17]; break; } case 40: // Gaussian case 41: case 42: case 43: { *width=igdstmpl[7]; *height=igdstmpl[8]; *iscan=igdstmpl[18]; break; } case 90: // Space View/Orthographic { *width=igdstmpl[7]; *height=igdstmpl[8]; *iscan=igdstmpl[16]; break; } case 110: // Equatorial Azimuthal { *width=igdstmpl[7]; *height=igdstmpl[8]; *iscan=igdstmpl[15]; break; } default: { *width=0; *height=0; *iscan=0; break; } } // end switch } else { *width=0; *height=0; } if (igds != 0) free(igds); if (igdstmpl != 0) free(igdstmpl); if (list_opt != 0) free(list_opt); return 0; } g2clib-1.6.0/getpoly.c0000644002373300042670000000425012522400361014346 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" g2int g2_unpack3(unsigned char *,g2int *,g2int **,g2int **, g2int *,g2int **,g2int *); g2int getpoly(unsigned char *csec3,g2int *jj,g2int *kk,g2int *mm) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: getpoly // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-11 // // ABSTRACT: This subroutine returns the J, K, and M pentagonal resolution // parameters specified in a GRIB Grid Definition Section used // spherical harmonic coefficients using GDT 5.50 through 5.53 // // PROGRAM HISTORY LOG: // 2002-12-11 Gilbert // // USAGE: int getpoly(unsigned char *csec3,g2int *jj,g2int *kk,g2int *mm) // INPUT ARGUMENTS: // csec3 - Character array that contains the packed GRIB2 GDS // // OUTPUT ARGUMENTS: // JJ = J - pentagonal resolution parameter // KK = K - pentagonal resolution parameter // MM = M - pentagonal resolution parameter // // REMARKS: Returns JJ, KK, and MM set to zero, if grid template // not recognized. // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { g2int *igdstmpl,*list_opt; g2int *igds; g2int iofst,igdtlen,num_opt,jerr; iofst=0; // set offset to beginning of section jerr=g2_unpack3(csec3,&iofst,&igds,&igdstmpl, &igdtlen,&list_opt,&num_opt); if (jerr == 0) { switch ( igds[4] ) // Template number { case 50: // Spherical harmonic coefficients case 51: case 52: case 53: { *jj=igdstmpl[0]; *kk=igdstmpl[1]; *mm=igdstmpl[2]; break; } default: { *jj=0; *kk=0; *mm=0; break; } } // end switch } else { *jj=0; *kk=0; *mm=0; } if (igds != 0) free(igds); if (igdstmpl != 0) free(igdstmpl); if (list_opt != 0) free(list_opt); return 0; } g2clib-1.6.0/grib2.h0000755002373300042670000003107212650420041013701 0ustar Boi.Vuongglobal#ifndef _grib2_H #define _grib2_H #include<stdio.h> #define G2_VERSION "g2clib-1.6.0" /* . . . . // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-25 // // PROGRAM HISTORY LOG: // 2002-10-25 Gilbert // 2009-01-14 Vuong Changed struct template to gtemplate // // 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. */ #ifdef __64BIT__ typedef int g2int; typedef unsigned int g2intu; #else typedef long g2int; typedef unsigned long g2intu; #endif typedef float g2float; struct gtemplate { g2int type; /* 3=Grid Defintion Template. */ /* 4=Product Defintion Template. */ /* 5=Data Representation Template. */ g2int num; /* template number. */ g2int maplen; /* number of entries in the static part */ /* of the template. */ g2int *map; /* num of octets of each entry in the */ /* static part of the template. */ g2int needext; /* indicates whether or not the template needs */ /* to be extended. */ g2int extlen; /* number of entries in the template extension. */ g2int *ext; /* num of octets of each entry in the extension */ /* part of the template. */ }; typedef struct gtemplate gtemplate; struct gribfield { g2int version,discipline; g2int *idsect; g2int idsectlen; unsigned char *local; g2int locallen; g2int ifldnum; g2int griddef,ngrdpts; g2int numoct_opt,interp_opt,num_opt; g2int *list_opt; g2int igdtnum,igdtlen; g2int *igdtmpl; g2int ipdtnum,ipdtlen; g2int *ipdtmpl; g2int num_coord; g2float *coord_list; g2int ndpts,idrtnum,idrtlen; g2int *idrtmpl; g2int unpacked; g2int expanded; g2int ibmap; g2int *bmap; g2float *fld; }; typedef struct gribfield gribfield; /* Prototypes for unpacking API */ void seekgb(FILE *,g2int ,g2int ,g2int *,g2int *); g2int g2_info(unsigned char *,g2int *,g2int *,g2int *,g2int *); g2int g2_getfld(unsigned char *,g2int ,g2int ,g2int ,gribfield **); void g2_free(gribfield *); /* Prototypes for packing API */ g2int g2_create(unsigned char *,g2int *,g2int *); g2int g2_addlocal(unsigned char *,unsigned char *,g2int ); g2int g2_addgrid(unsigned char *,g2int *,g2int *,g2int *,g2int ); g2int g2_addfield(unsigned char *,g2int ,g2int *, g2float *,g2int ,g2int ,g2int *, g2float *,g2int ,g2int ,g2int *); g2int g2_gribend(unsigned char *); /* Prototypes for supporting routines */ extern double int_power(double, g2int ); extern void mkieee(g2float *,g2int *,g2int); void rdieee(g2int *,g2float *,g2int ); extern gtemplate *getpdstemplate(g2int); extern gtemplate *extpdstemplate(g2int,g2int *); extern gtemplate *getdrstemplate(g2int); extern gtemplate *extdrstemplate(g2int,g2int *); extern gtemplate *getgridtemplate(g2int); extern gtemplate *extgridtemplate(g2int,g2int *); extern void simpack(g2float *,g2int,g2int *,unsigned char *,g2int *); extern void compack(g2float *,g2int,g2int,g2int *,unsigned char *,g2int *); void misspack(g2float *,g2int ,g2int ,g2int *, unsigned char *, g2int *); void gbit(unsigned char *,g2int *,g2int ,g2int ); void sbit(unsigned char *,g2int *,g2int ,g2int ); void gbits(unsigned char *,g2int *,g2int ,g2int ,g2int ,g2int ); void sbits(unsigned char *,g2int *,g2int ,g2int ,g2int ,g2int ); int pack_gp(g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *, g2int *); #endif /* _grib2_H */ g2clib-1.6.0/grib2c.doc0000755002373300042670000013412112522400361014362 0ustar Boi.Vuongglobal 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: // //$$$ g2clib-1.6.0/gridtemplates.c0000755002373300042670000001554512522400361015543 0ustar Boi.Vuongglobal#include <stdlib.h> #include "grib2.h" #include "gridtemplates.h" g2int getgridindex(g2int number) /*!$$$ SUBPROGRAM DOCUMENTATION BLOCK ! . . . . ! SUBPROGRAM: getgridindex ! PRGMMR: Gilbert ORG: W/NP11 DATE: 2001-06-28 ! ! ABSTRACT: This function returns the index of specified Grid ! Definition Template 3.NN (NN=number) in array templates. ! ! PROGRAM HISTORY LOG: ! 2001-06-28 Gilbert ! 2007-08-16 Vuong - Added GDT 3.204 Curvilinear Orthogonal Grid ! 2008-07-08 Vuong - Added GDT 3.32768 Rotate Lat/Lon E-grid (Arakawa) ! 2009-01-14 Vuong - Changed structure name template to gtemplate ! 2010-05-11 Vuong - Added GDT 3.32769 Rotate Lat/Lon Non-E Staggered grid (Arakawa) ! 2013-08-06 Vuong - Added GDT 3.4,3.5,3.12,3.101,3.140 ! ! USAGE: index=getgridindex(number) ! INPUT ARGUMENT LIST: ! number - NN, indicating the number of the Grid Definition ! Template 3.NN that is being requested. ! ! RETURNS: Index of GDT 3.NN in array templates, if template exists. ! = -1, otherwise. ! ! REMARKS: None ! ! ATTRIBUTES: ! LANGUAGE: C ! MACHINE: IBM SP ! !$$$*/ { g2int j,getgridindex=-1; for (j=0;j<MAXGRIDTEMP;j++) { if (number == templatesgrid[j].template_num) { getgridindex=j; return(getgridindex); } } return(getgridindex); } gtemplate *getgridtemplate(g2int number) /*!$$$ SUBPROGRAM DOCUMENTATION BLOCK ! . . . . ! SUBPROGRAM: getgridtemplate ! PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-05-09 ! ! ABSTRACT: This subroutine returns grid template information for a ! specified Grid Definition Template 3.NN. ! The number of entries in the template is returned along with a map ! of the number of octets occupied by each entry. Also, a flag is ! returned to indicate whether the template would need to be extended. ! ! PROGRAM HISTORY LOG: ! 2000-05-09 Gilbert ! 2007-08-16 Vuong - Added GDT 3.204 Curvilinear Orthogonal Grid ! 2008-07-08 Vuong - Added GDT 3.32768 Rotate Lat/Lon E-grid (Arakawa) ! 2010-05-11 Vuong - Added GDT 3.32769 Rotate Lat/Lon Non-E Staggered grid (Arakawa) ! 2009-01-14 Vuong - Changed structure name template to gtemplate ! ! USAGE: gtemplate *getgridtemplate(number) ! INPUT ARGUMENT LIST: ! number - NN, indicating the number of the Grid Definition ! Template 3.NN that is being requested. ! ! RETURN VALUE: ! - Pointer to the returned template struct. ! Returns NULL pointer, if template not found. ! ! REMARKS: None ! ! ATTRIBUTES: ! LANGUAGE: C ! MACHINE: IBM SP ! !$$$*/ { g2int index; gtemplate *new; index=getgridindex(number); if (index != -1) { new=(gtemplate *)malloc(sizeof(gtemplate)); new->type=3; new->num=templatesgrid[index].template_num; new->maplen=templatesgrid[index].mapgridlen; new->needext=templatesgrid[index].needext; new->map=(g2int *)templatesgrid[index].mapgrid; new->extlen=0; new->ext=0; //NULL return(new); } else { printf("getgridtemplate: GDT Template 3.%d not defined.\n",(int)number); return(0); //NULL } return(0); //NULL } gtemplate *extgridtemplate(g2int number,g2int *list) /*!$$$ SUBPROGRAM DOCUMENTATION BLOCK ! . . . . ! SUBPROGRAM: extgridtemplate ! PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-05-09 ! ! ABSTRACT: This subroutine generates the remaining octet map for a ! given Grid Definition Template, if required. Some Templates can ! vary depending on data values given in an earlier part of the ! Template, and it is necessary to know some of the earlier entry ! values to generate the full octet map of the Template. ! ! PROGRAM HISTORY LOG: ! 2000-05-09 Gilbert ! 2008-07-08 Vuong - Added GDT 3.32768 Rotate Lat/Lon E-grid (Arakawa) ! 2009-01-14 Vuong - Changed structure name template to gtemplate ! 2010-05-11 Vuong - Added GDT 3.32769 Rotate Lat/Lon Non-E Staggered grid (Arakawa) ! 2013-08-06 Vuong - Added GDT 3.4,3.5,3.12,3.101,3.140 ! ! USAGE: CALL extgridtemplate(number,list) ! INPUT ARGUMENT LIST: ! number - NN, indicating the number of the Grid Definition ! Template 3.NN that is being requested. ! list() - The list of values for each entry in ! the Grid Definition Template. ! ! RETURN VALUE: ! - Pointer to the returned template struct. ! Returns NULL pointer, if template not found. ! ! ATTRIBUTES: ! LANGUAGE: C ! MACHINE: IBM SP ! !$$$*/ { gtemplate *new; g2int index,i; index=getgridindex(number); if (index == -1) return(0); new=getgridtemplate(number); if ( ! new->needext ) return(new); if ( number == 120 ) { new->extlen=list[1]*2; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { if ( i%2 == 0 ) { new->ext[i]=2; } else { new->ext[i]=-2; } } } else if ( number == 4 ) { new->extlen=list[7]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { new->ext[i]=4; } new->extlen=list[8]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { new->ext[i]=-4; } } else if ( number == 5 ) { new->extlen=list[7]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { new->ext[i]=4; } new->extlen=list[8]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { new->ext[i]=-4; } } else if ( number == 1000 ) { new->extlen=list[19]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { new->ext[i]=4; } } else if ( number == 1200 ) { new->extlen=list[15]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { new->ext[i]=4; } } return(new); } g2clib-1.6.0/gridtemplates.h0000755002373300042670000001357312522400361015547 0ustar Boi.Vuongglobal#ifndef _gridtemplates_H #define _gridtemplates_H #include "grib2.h" // PRGMMR: Gilbert ORG: W/NP11 DATE: 2001-10-26 // // ABSTRACT: This Fortran Module contains info on all the available // GRIB2 Grid Definition Templates used in Section 3 (GDS). // The information decribing each template is stored in the // gridtemplate structure defined below. // // Each Template has three parts: The number of entries in the template // (mapgridlen); A map of the template (mapgrid), which contains the // number of octets in which to pack each of the template values; and // a logical value (needext) that indicates whether the Template needs // to be extended. In some cases the number of entries in a template // can vary depending upon values specified in the "static" part of // the template. ( See Template 3.120 as an example ) // // NOTE: Array mapgrid contains the number of octets in which the // corresponding template values will be stored. A negative value in // mapgrid is used to indicate that the corresponding template entry can // contain negative values. This information is used later when packing // (or unpacking) the template data values. Negative data values in GRIB // are stored with the left most bit set to one, and a negative number // of octets value in mapgrid[] indicates that this possibility should // be considered. The number of octets used to store the data value // in this case would be the absolute value of the negative value in // mapgrid[]. // // PROGRAM HISTORY LOG: // // 2001-10-26 Gilbert // 2007-08-16 Vuong - Added GDT 3.204 Curvilinear Orthogonal Grid // 2008-07-08 Vuong - Added GDT 3.32768 Rot Lat/Lon E-grid (Arakawa) // 2010-05-11 Vuong - Added GDT 3.32769 Rotate Lat/Lon Non-E Staggered grid (Arakawa) // 2013-08-06 Vuong - Added GDT 3.4,3.5,3.12,3.101,3.140 // //////////////////////////////////////////////////////////////////// #define MAXGRIDTEMP 31 // maximum number of templates #define MAXGRIDMAPLEN 200 // maximum template map length struct gridtemplate { g2int template_num; g2int mapgridlen; g2int needext; g2int mapgrid[MAXGRIDMAPLEN]; }; const struct gridtemplate templatesgrid[MAXGRIDTEMP] = { // 3.0: Lat/Lon grid { 0, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} }, // 3.1: Rotated Lat/Lon grid { 1, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4} }, // 3.2: Stretched Lat/Lon grid { 2, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,-4} }, // 3.3: Stretched & Rotated Lat/Lon grid { 3, 25, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4,-4,4,-4} }, // Added GDT 3.4,3.5 (08/05/2013) // 3.4: Variable resolution Latitude/Longitude { 4, 13, 1, {1,1,4,1,4,1,4,4,4,4,4,1,1} }, // 3.5: Variable resolution rotate Latitude/Longitude { 5, 16, 1, {1,1,4,1,4,1,4,4,4,4,4,1,1,-4,4,4} }, // 3.12: Transverse Mercator {12, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,1,4,4,-4,-4,-4,-4} }, // 3.101: General unstructured grid {101, 4, 0, {1,4,1,-4} }, // 3.140: Lambert Azimuthal Equal Area Projection {140, 17, 0, {1,1,4,1,4,1,4,4,4,-4,4,4,4,1,4,4,1} }, // // 3.10: Mercator {10, 19, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,-4,4,1,4,4,4} }, // 3.20: Polar Stereographic Projection {20, 18, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1} }, // 3.30: Lambert Conformal {30, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1,-4,-4,-4,4} }, // 3.31: Albers equal area {31, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1,-4,-4,-4,4} }, // 3.40: Guassian Lat/Lon {40, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} }, // 3.41: Rotated Gaussian Lat/Lon {41, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4} }, // 3.42: Stretched Gaussian Lat/Lon {42, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,-4} }, // 3.43: Stretched and Rotated Gaussian Lat/Lon {43, 25, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4,-4,4,-4} }, // 3.50: Spherical Harmonic Coefficients {50, 5, 0, {4,4,4,1,1} }, // 3.51: Rotated Spherical Harmonic Coefficients {51, 8, 0, {4,4,4,1,1,-4,4,4} }, // 3.52: Stretched Spherical Harmonic Coefficients {52, 8, 0, {4,4,4,1,1,-4,4,-4} }, // 3.53: Stretched and Rotated Spherical Harmonic Coefficients {53, 11, 0, {4,4,4,1,1,-4,4,4,-4,4,-4} }, // 3.90: Space View Perspective or orthographic {90, 21, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,4,4,4,4,1,4,4,4,4} }, // 3.100: Triangular grid based on an icosahedron {100, 11, 0, {1,1,2,1,-4,4,4,1,1,1,4} }, // 3.110: Equatorial Azimuthal equidistant {110, 16, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,4,4,1,1} }, // 3.120: Azimuth-range projection {120, 7, 1, {4,4,-4,4,4,4,1} }, // 3.204: Curvilinear Orthogonal Grid {204, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} }, // 3.32768: Rot Lat/Lon E-grid (Arakawa) {32768, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} }, // 3.32769: Rot Lat/Lon Non-E Staggered grid (Arakawa) {32769, 21, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,4,4} }, // 3.1000: Cross Section Grid {1000, 20, 1, {1,1,4,1,4,1,4,4,4,4,-4,4,1,4,4,1,2,1,1,2} }, // 3.1100: Hovmoller Diagram Grid {1100, 28, 0, {1,1,4,1,4,1,4,4,4,4,-4,4,1,-4,4,1,4,1,-4,1,1,-4,2,1,1,1,1,1} }, // 3.1200: Time Section Grid {1200, 16, 1, {4,1,-4,1,1,-4,2,1,1,1,1,1,2,1,1,2} } } ; #endif /* _gridtemplates_H */ g2clib-1.6.0/int_power.c0000755002373300042670000000071612522400361014677 0ustar Boi.Vuongglobal#include "grib2.h" /* * w. ebisuzaki * * return x**y * * * input: double x * int y */ double int_power(double x, g2int y) { double value; if (y < 0) { y = -y; x = 1.0 / x; } value = 1.0; while (y) { if (y & 1) { value *= x; } x = x * x; y >>= 1; } return value; } g2clib-1.6.0/jpcpack.c0000755002373300042670000001512312522400361014302 0ustar Boi.Vuongglobal#include <stdlib.h> #include <math.h> #include "grib2.h" int enc_jpeg2000(unsigned char *,g2int ,g2int ,g2int , g2int , g2int, g2int , char *, g2int ); void jpcpack(g2float *fld,g2int width,g2int height,g2int *idrstmpl, unsigned char *cpack,g2int *lcpack) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: jpcpack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2003-08-17 // // ABSTRACT: This subroutine packs up a data field into a JPEG2000 code stream. // After the data field is scaled, and the reference value is subtracted out, // it is treated as a grayscale image and passed to a JPEG2000 encoder. // It also fills in GRIB2 Data Representation Template 5.40 or 5.40000 with // the appropriate values. // // PROGRAM HISTORY LOG: // 2003-08-17 Gilbert // 2004-11-92 Gilbert - Fixed bug encountered when packing a near constant // field. // 2004-07-19 Gilbert - Added check on whether the jpeg2000 encoding was // successful. If not, try again with different encoder // options. // 2005-05-10 Gilbert - Imposed minimum size on cpack, used to hold encoded // bit string. // // USAGE: jpcpack(g2float *fld,g2int width,g2int height,g2int *idrstmpl, // unsigned char *cpack,g2int *lcpack); // INPUT ARGUMENT LIST: // fld[] - Contains the data values to pack // width - number of points in the x direction // height - number of points in the y direction // idrstmpl - Contains the array of values for Data Representation // Template 5.40 or 5.40000 // [0] = Reference value - ignored on input // [1] = Binary Scale Factor // [2] = Decimal Scale Factor // [3] = number of bits for each data value - ignored on input // [4] = Original field type - currently ignored on input // Data values assumed to be reals. // [5] = 0 - use lossless compression // = 1 - use lossy compression // [6] = Desired compression ratio, if idrstmpl[5]=1. // Set to 255, if idrstmpl[5]=0. // lcpack - size of array cpack[] // // OUTPUT ARGUMENT LIST: // idrstmpl - Contains the array of values for Data Representation // Template 5.0 // [0] = Reference value - set by jpcpack routine. // [1] = Binary Scale Factor - unchanged from input // [2] = Decimal Scale Factor - unchanged from input // [3] = Number of bits containing each grayscale pixel value // [4] = Original field type - currently set = 0 on output. // Data values assumed to be reals. // [5] = 0 - use lossless compression // = 1 - use lossy compression // [6] = Desired compression ratio, if idrstmpl[5]=1 // cpack - The packed data field // lcpack - length of packed field in cpack. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { g2int *ifld; static g2float alog2=0.69314718; // ln(2.0) g2int j,nbits,imin,imax,maxdif; g2int ndpts,nbytes,nsize,retry; g2float bscale,dscale,rmax,rmin,temp; unsigned char *ctemp; ifld=0; ndpts=width*height; bscale=int_power(2.0,-idrstmpl[1]); dscale=int_power(10.0,idrstmpl[2]); // // Find max and min values in the data // rmax=fld[0]; rmin=fld[0]; for (j=1;j<ndpts;j++) { if (fld[j] > rmax) rmax=fld[j]; if (fld[j] < rmin) rmin=fld[j]; } if (idrstmpl[1] == 0) maxdif = (g2int) (rint(rmax*dscale) - rint(rmin*dscale)); else maxdif = (g2int)rint( (rmax-rmin)*dscale*bscale ); // // If max and min values are not equal, pack up field. // If they are equal, we have a constant field, and the reference // value (rmin) is the value for each point in the field and // set nbits to 0. // if ( rmin != rmax && maxdif != 0 ) { ifld=(g2int *)malloc(ndpts*sizeof(g2int)); // // Determine which algorithm to use based on user-supplied // binary scale factor and number of bits. // if (idrstmpl[1] == 0) { // // No binary scaling and calculate minumum number of // bits in which the data will fit. // imin=(g2int)rint(rmin*dscale); imax=(g2int)rint(rmax*dscale); maxdif=imax-imin; temp=log((double)(maxdif+1))/alog2; nbits=(g2int)ceil(temp); rmin=(g2float)imin; // scale data for(j=0;j<ndpts;j++) ifld[j]=(g2int)rint(fld[j]*dscale)-imin; } else { // // Use binary scaling factor and calculate minumum number of // bits in which the data will fit. // rmin=rmin*dscale; rmax=rmax*dscale; maxdif=(g2int)rint((rmax-rmin)*bscale); temp=log((double)(maxdif+1))/alog2; nbits=(g2int)ceil(temp); // scale data for (j=0;j<ndpts;j++) ifld[j]=(g2int)rint(((fld[j]*dscale)-rmin)*bscale); } // // Pack data into full octets, then do JPEG 2000 encode. // and calculate the length of the packed data in bytes // retry=0; nbytes=(nbits+7)/8; nsize=*lcpack; // needed for input to enc_jpeg2000 ctemp=calloc(ndpts,nbytes); sbits(ctemp,ifld,0,nbytes*8,0,ndpts); *lcpack=(g2int)enc_jpeg2000(ctemp,width,height,nbits,idrstmpl[5],idrstmpl[6],retry,(char *)cpack,nsize); if (*lcpack <= 0) { printf("jpcpack: ERROR Packing JPC = %d\n",(int)*lcpack); if ( *lcpack == -3 ) { retry=1; *lcpack=(g2int)enc_jpeg2000(ctemp,width,height,nbits,idrstmpl[5],idrstmpl[6],retry,(char *)cpack,nsize); if ( *lcpack <= 0 ) printf("jpcpack: Retry Failed.\n"); else printf("jpcpack: Retry Successful.\n"); } } free(ctemp); } else { nbits=0; *lcpack=0; } // // Fill in ref value and number of bits in Template 5.0 // mkieee(&rmin,idrstmpl+0,1); // ensure reference value is IEEE format idrstmpl[3]=nbits; idrstmpl[4]=0; // original data were reals if (idrstmpl[5] == 0) idrstmpl[6]=255; // lossy not used if (ifld != 0) free(ifld); } g2clib-1.6.0/jpcunpack.c0000755002373300042670000000405212522400361014644 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" int dec_jpeg2000(char *,g2int ,g2int *); g2int jpcunpack(unsigned char *cpack,g2int len,g2int *idrstmpl,g2int ndpts, g2float *fld) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: jpcunpack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2003-08-27 // // ABSTRACT: This subroutine unpacks a data field that was packed into a // JPEG2000 code stream // using info from the GRIB2 Data Representation Template 5.40 or 5.40000. // // PROGRAM HISTORY LOG: // 2003-08-27 Gilbert // // USAGE: jpcunpack(unsigned char *cpack,g2int len,g2int *idrstmpl,g2int ndpts, // g2float *fld) // INPUT ARGUMENT LIST: // cpack - The packed data field (character*1 array) // len - length of packed field cpack(). // idrstmpl - Pointer to array of values for Data Representation // Template 5.40 or 5.40000 // ndpts - The number of data values to unpack // // OUTPUT ARGUMENT LIST: // fld[] - Contains the unpacked data values // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { g2int *ifld; g2int j,nbits,iret; g2float ref,bscale,dscale; rdieee(idrstmpl+0,&ref,1); bscale = int_power(2.0,idrstmpl[1]); dscale = int_power(10.0,-idrstmpl[2]); nbits = idrstmpl[3]; // // if nbits equals 0, we have a constant field where the reference value // is the data value at each gridpoint // if (nbits != 0) { ifld=(g2int *)calloc(ndpts,sizeof(g2int)); if ( ifld == 0 ) { fprintf(stderr,"Could not allocate space in jpcunpack.\n Data field NOT upacked.\n"); return(1); } iret=(g2int)dec_jpeg2000(cpack,len,ifld); for (j=0;j<ndpts;j++) { fld[j]=(((g2float)ifld[j]*bscale)+ref)*dscale; } free(ifld); } else { for (j=0;j<ndpts;j++) fld[j]=ref; } return(0); } g2clib-1.6.0/main.c0000755002373300042670000000253512522400361013616 0ustar Boi.Vuongglobal#include <stdio.h> #include "grib2.h" extern gtemplate *getdrstemplate(int); extern gtemplate *extdrstemplate(int,g2int *); extern gtemplate *getgridtemplate(int); extern gtemplate *extgridtemplate(int,g2int *); extern gtemplate *getpdstemplate(int); extern gtemplate *extpdstemplate(int,g2int *); /* int main(void) { char mug[]={'A','B','C','D'}; int imug[20]; int i,num=8; gbits(mug,imug,0,4,0,num); for (i=0;i<num;i++) { printf(" %d %x \n",imug[i],imug[i]); } } int main(void) { char mug[10]; int imug[4]={41,42,43,44}; int i,num=4; sbits(mug,imug,0,4,0,num); for (i=0;i<num;i++) { printf(" %c %x \n",mug[i],mug[i]); } } */ int main(void) { gtemplate *t; int *imug; g2int list[100]={0,10,0,0,0,0,0,0,0,0,0,5,0,6,0,0,0,0,0,0,0,3,0,0,0,5,7,0,0,0,0,0,0,0,0,0,2,1}; int i,len,need,iret,num=13; /* t=getdrstemplate(num); */ /* t=getgridtemplate(num); */ t=getpdstemplate(num); printf(" sagret1: %x %d %d %d %d %d\n",t,t->type,t->num,t->maplen,t->needext,t->extlen); for (i=0;i<t->maplen;i++) { printf(" %d ",t->map[i]); } printf(" \n"); /* t=extdrstemplate(num,list); */ /* t=extgridtemplate(num,list);*/ t=extpdstemplate(num,list); printf(" sagret1: %x %d %d %d %d %d\n",t,t->type,t->num,t->maplen,t->needext,t->extlen); for (i=0;i<t->extlen;i++) { printf(" %d ",t->ext[i]); } printf(" \n"); } g2clib-1.6.0/mainhome.c0000755002373300042670000000456012522400361014467 0ustar Boi.Vuongglobal#include <stdio.h> #include "grib2.h" extern gtemplate *getdrstemplate(int); extern gtemplate *extdrstemplate(int,g2int *); /* int main(void) { char mug[]={'A','B','C','D'}; int imug[20]; int i,num=8; gbits(mug,imug,0,4,0,num); for (i=0;i<num;i++) { printf(" %d %x \n",imug[i],imug[i]); } } int main(void) { char mug[10]; int imug[4]={41,42,43,44}; int i,num=4; sbits(mug,imug,0,4,0,num); for (i=0;i<num;i++) { printf(" %c %x \n",mug[i],mug[i]); } } int main(void) { gtemplate *t; int *imug; g2int list[100]={0,0,0,0,0,0,0,0,0,0,0,5,0,6,0,0,0,0,0}; int i,len,need,iret,num=1; t=getdrstemplate(num); printf(" sagret1: %x %d %d %d %d %d\n",t,t->type,t->num,t->maplen,t->needext,t->extlen); for (i=0;i<t->maplen;i++) { printf(" %d ",t->map[i]); } printf(" \n"); t=extdrstemplate(num,list); printf(" sagret1: %x %d %d %d %d %d\n",t,t->type,t->num,t->maplen,t->needext,t->extlen); for (i=0;i<t->extlen;i++) { printf(" %d ",t->ext[i]); } printf(" \n"); } */ int main(void) { unsigned char mug[300],*cout; int iret,j; long iof=0; g2int *ids,idslen,*tmp,*igdt,igdtlen,*def,deflen,ip,ipdtlen,*ipdt; g2int idrtlen,*idrt,ndpts,drtnum; g2float crdlen,*crd; for (j=0;j<300;j++) { mug[j]=(char)0; } mug[1]=(char)0; mug[2]=(char)0; mug[3]=(char)21; mug[4]=(char)5; mug[8]=(char)254; mug[9]=(char)0; mug[10]=(char)0; mug[14]=(char)222; mug[16]=(char)66; mug[18]=(char)7; mug[22]=(char)128; mug[25]=(char)88; mug[29]=(char)111; mug[33]=(char)112; mug[37]=(char)113; mug[67]=(char)3; mug[68]=(char)3; mug[69]=(char)3; mug[70]=(char)3; mug[71]=(char)3; mug[72]=(char)3; // iret=g2_unpack1(mug,&iof,&ids,&idslen); // iret=g2_unpack2(mug,&iof,&idslen,&cout); // iret=g2_unpack3(mug,&iof,&ids,&igdt,&igdtlen,&def,&deflen); // iret=g2_unpack4(mug,&iof,&ip,&ipdt,&ipdtlen,&crd,&crdlen); iret=g2_unpack5(mug,&iof,&ndpts,&drtnum,&idrt,&idrtlen); printf(" SAGRET = %d %d %d %d\n",iret,(int)ndpts,(int)idrtlen,(int)drtnum); // tmp=*ids; // for (j=0;j<5;j++) { // printf(" %d ",(int)ids[j]); // } // printf("\n"); for (j=0;j<idrtlen;j++) { printf(" %d ",(int)idrt[j]); } // printf("\n"); // for (j=0;j<crdlen;j++) { // printf(" %d ",(int)crd[j]); // } printf("\n"); } g2clib-1.6.0/makefile0000755002373300042670000000426012650423225014231 0ustar Boi.VuongglobalSHELL=/bin/sh # If you want to enable support for PNG or JPEG2000 encoding/decoding, # you must specify -DUSE_PNG and/or -DUSE_JPEG2000 in the DEFS variable # for the C pre-processor # -DUSE_PNG requires libpng.a and libz.a # ( and png.h pngconf.h zconf.h zlib.h include files). # -DUSE_JPEG2000 requires libjasper.a # ( and all the jasper/*.h include files). # # In addition, INC must include all directories where the above # mentioned include files can be found. DEFS=-DUSE_JPEG2000 -DUSE_PNG # # Please make sure to include all idirectories where include files # can be found (jasper/*.h and png.h pngconf.h zconf.h zlib.h) # INC=-I/nwprod/lib/include/ # # This "C" source code contains many uses of the C++ # comment style "//". Please make sure you include the # appropriate compiler flag to allow the use of "//" comment indicators. # CFLAGS= -O3 -g -m64 $(INC) $(DEFS) -D__64BIT__ CC=gcc LIB=libg2c_v1.6.0.a ARFLAGS= all: $(LIB) $(LIB)(gridtemplates.o): gridtemplates.h $(LIB)(pdstemplates.o): pdstemplates.h $(LIB)(drstemplates.o): drstemplates.h $(LIB): $(LIB)(gridtemplates.o) \ $(LIB)(drstemplates.o) \ $(LIB)(pdstemplates.o) \ $(LIB)(gbits.o) \ $(LIB)(g2_unpack1.o) \ $(LIB)(g2_unpack2.o) \ $(LIB)(g2_unpack3.o) \ $(LIB)(g2_unpack4.o) \ $(LIB)(g2_unpack5.o) \ $(LIB)(g2_unpack6.o) \ $(LIB)(g2_unpack7.o) \ $(LIB)(g2_free.o) \ $(LIB)(g2_info.o) \ $(LIB)(g2_getfld.o) \ $(LIB)(simunpack.o) \ $(LIB)(comunpack.o) \ $(LIB)(pack_gp.o) \ $(LIB)(reduce.o) \ $(LIB)(specpack.o) \ $(LIB)(specunpack.o) \ $(LIB)(rdieee.o) \ $(LIB)(mkieee.o) \ $(LIB)(int_power.o) \ $(LIB)(simpack.o) \ $(LIB)(compack.o) \ $(LIB)(cmplxpack.o) \ $(LIB)(misspack.o) \ $(LIB)(jpcpack.o) \ $(LIB)(jpcunpack.o) \ $(LIB)(pngpack.o) \ $(LIB)(pngunpack.o) \ $(LIB)(dec_jpeg2000.o) \ $(LIB)(enc_jpeg2000.o) \ $(LIB)(dec_png.o) \ $(LIB)(enc_png.o) \ $(LIB)(g2_create.o) \ $(LIB)(g2_addlocal.o) \ $(LIB)(g2_addgrid.o) \ $(LIB)(g2_addfield.o) \ $(LIB)(g2_gribend.o) \ $(LIB)(getdim.o) \ $(LIB)(g2_miss.o) \ $(LIB)(getpoly.o) \ $(LIB)(seekgb.o) .c.a: $(CC) -c $(CFLAGS) $< ar $(ARFLAGS) -ruv $@ $*.o rm -f $*.o g2clib-1.6.0/misspack.c0000755002373300042670000004541012522400361014503 0ustar Boi.Vuongglobal#include <stdlib.h> #include <math.h> #include "grib2.h" void misspack(g2float *fld,g2int ndpts,g2int idrsnum,g2int *idrstmpl, unsigned char *cpack, g2int *lcpack) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: misspack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-06-21 // // ABSTRACT: This subroutine packs up a data field using a complex // packing algorithm as defined in the GRIB2 documention. It // supports GRIB2 complex packing templates with or without // spatial differences (i.e. DRTs 5.2 and 5.3). // It also fills in GRIB2 Data Representation Template 5.2 or 5.3 // with the appropriate values. // This version assumes that Missing Value Management is being used and that // 1 or 2 missing values appear in the data. // // PROGRAM HISTORY LOG: // 2000-06-21 Gilbert // // USAGE: misspack(g2float *fld,g2int ndpts,g2int idrsnum,g2int *idrstmpl, // unsigned char *cpack, g2int *lcpack) // INPUT ARGUMENT LIST: // fld[] - Contains the data values to pack // ndpts - The number of data values in array fld[] // idrsnum - Data Representation Template number 5.N // Must equal 2 or 3. // idrstmpl - Contains the array of values for Data Representation // Template 5.2 or 5.3 // [0] = Reference value - ignored on input // [1] = Binary Scale Factor // [2] = Decimal Scale Factor // . // . // [6] = Missing value management // [7] = Primary missing value // [8] = Secondary missing value // . // . // [16] = Order of Spatial Differencing ( 1 or 2 ) // . // . // // OUTPUT ARGUMENT LIST: // idrstmpl - Contains the array of values for Data Representation // Template 5.3 // [0] = Reference value - set by misspack routine. // [1] = Binary Scale Factor - unchanged from input // [2] = Decimal Scale Factor - unchanged from input // . // . // cpack - The packed data field (character*1 array) // *lcpack - length of packed field cpack(). // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$ { g2int *ifld, *ifldmiss, *jfld; g2int *jmin, *jmax, *lbit; static g2int zero=0; g2int *gref, *gwidth, *glen; g2int glength, grpwidth; g2int i, n, iofst, imin, ival1, ival2, isd, minsd, nbitsd; g2int nbitsgref, left, iwmax, ngwidthref, nbitsgwidth, ilmax; g2int nglenref, nglenlast, nbitsglen, ij; g2int j, missopt, nonmiss, itemp, maxorig, nbitorig, miss1, miss2; g2int ngroups, ng, num0, num1, num2; g2int imax, lg, mtemp, ier, igmax; g2int kfildo, minpk, inc, maxgrps, ibit, jbit, kbit, novref, lbitref; g2float rmissp, rmisss, bscale, dscale, rmin, temp; static g2int simple_alg = 0; static g2float alog2=0.69314718; // ln(2.0) static g2int one=1; bscale=int_power(2.0,-idrstmpl[1]); dscale=int_power(10.0,idrstmpl[2]); missopt=idrstmpl[6]; if ( missopt != 1 && missopt != 2 ) { printf("misspack: Unrecognized option.\n"); *lcpack=-1; return; } else { // Get missing values rdieee(idrstmpl+7,&rmissp,1); if (missopt == 2) rdieee(idrstmpl+8,&rmisss,1); } // // Find min value of non-missing values in the data, // AND set up missing value mapping of the field. // ifldmiss = calloc(ndpts,sizeof(g2int)); rmin=1E+37; if ( missopt == 1 ) { // Primary missing value only for ( j=0; j<ndpts; j++) { if (fld[j] == rmissp) { ifldmiss[j]=1; } else { ifldmiss[j]=0; if (fld[j] < rmin) rmin=fld[j]; } } } if ( missopt == 2 ) { // Primary and secondary missing values for ( j=0; j<ndpts; j++ ) { if (fld[j] == rmissp) { ifldmiss[j]=1; } else if (fld[j] == rmisss) { ifldmiss[j]=2; } else { ifldmiss[j]=0; if (fld[j] < rmin) rmin=fld[j]; } } } // // Allocate work arrays: // Note: -ifldmiss[j],j=0,ndpts-1 is a map of original field indicating // which of the original data values // are primary missing (1), sencondary missing (2) or non-missing (0). // -jfld[j],j=0,nonmiss-1 is a subarray of just the non-missing values // from the original field. // //if (rmin != rmax) { iofst=0; ifld = calloc(ndpts,sizeof(g2int)); jfld = calloc(ndpts,sizeof(g2int)); gref = calloc(ndpts,sizeof(g2int)); gwidth = calloc(ndpts,sizeof(g2int)); glen = calloc(ndpts,sizeof(g2int)); // // Scale original data // nonmiss=0; if (idrstmpl[1] == 0) { // No binary scaling imin=(g2int)rint(rmin*dscale); //imax=(g2int)rint(rmax*dscale); rmin=(g2float)imin; for ( j=0; j<ndpts; j++) { if (ifldmiss[j] == 0) { jfld[nonmiss]=(g2int)rint(fld[j]*dscale)-imin; nonmiss++; } } } else { // Use binary scaling factor rmin=rmin*dscale; //rmax=rmax*dscale; for ( j=0; j<ndpts; j++ ) { if (ifldmiss[j] == 0) { jfld[nonmiss]=(g2int)rint(((fld[j]*dscale)-rmin)*bscale); nonmiss++; } } } // // Calculate Spatial differences, if using DRS Template 5.3 // if (idrsnum == 3) { // spatial differences if (idrstmpl[16]!=1 && idrstmpl[16]!=2) idrstmpl[16]=2; if (idrstmpl[16] == 1) { // first order ival1=jfld[0]; for ( j=nonmiss-1; j>0; j--) jfld[j]=jfld[j]-jfld[j-1]; jfld[0]=0; } else if (idrstmpl[16] == 2) { // second order ival1=jfld[0]; ival2=jfld[1]; for ( j=nonmiss-1; j>1; j--) jfld[j]=jfld[j]-(2*jfld[j-1])+jfld[j-2]; jfld[0]=0; jfld[1]=0; } // // subtract min value from spatial diff field // isd=idrstmpl[16]; minsd=jfld[isd]; for ( j=isd; j<nonmiss; j++ ) if ( jfld[j] < minsd ) minsd=jfld[j]; for ( j=isd; j<nonmiss; j++ ) jfld[j]=jfld[j]-minsd; // // find num of bits need to store minsd and add 1 extra bit // to indicate sign // temp=log((double)(abs(minsd)+1))/alog2; nbitsd=(g2int)ceil(temp)+1; // // find num of bits need to store ifld[0] ( and ifld[1] // if using 2nd order differencing ) // maxorig=ival1; if (idrstmpl[16]==2 && ival2>ival1) maxorig=ival2; temp=log((double)(maxorig+1))/alog2; nbitorig=(g2int)ceil(temp)+1; if (nbitorig > nbitsd) nbitsd=nbitorig; // increase number of bits to even multiple of 8 ( octet ) if ( (nbitsd%8) != 0) nbitsd=nbitsd+(8-(nbitsd%8)); // // Store extra spatial differencing info into the packed // data section. // if (nbitsd != 0) { // pack first original value if (ival1 >= 0) { sbit(cpack,&ival1,iofst,nbitsd); iofst=iofst+nbitsd; } else { sbit(cpack,&one,iofst,1); iofst=iofst+1; itemp=abs(ival1); sbit(cpack,&itemp,iofst,nbitsd-1); iofst=iofst+nbitsd-1; } if (idrstmpl[16] == 2) { // pack second original value if (ival2 >= 0) { sbit(cpack,&ival2,iofst,nbitsd); iofst=iofst+nbitsd; } else { sbit(cpack,&one,iofst,1); iofst=iofst+1; itemp=abs(ival2); sbit(cpack,&itemp,iofst,nbitsd-1); iofst=iofst+nbitsd-1; } } // pack overall min of spatial differences if (minsd >= 0) { sbit(cpack,&minsd,iofst,nbitsd); iofst=iofst+nbitsd; } else { sbit(cpack,&one,iofst,1); iofst=iofst+1; itemp=abs(minsd); sbit(cpack,&itemp,iofst,nbitsd-1); iofst=iofst+nbitsd-1; } } //print *,'SDp ',ival1,ival2,minsd,nbitsd } // end of spatial diff section // // Expand non-missing data values to original grid. // miss1=jfld[0]; for ( j=0; j<nonmiss; j++) if (jfld[j] < miss1) miss1 = jfld[j]; miss1--; miss2=miss1-1; n=0; for ( j=0; j<ndpts; j++) { if ( ifldmiss[j] == 0 ) { ifld[j]=jfld[n]; n++; } else if ( ifldmiss[j] == 1 ) { ifld[j]=miss1; } else if ( ifldmiss[j] == 2 ) { ifld[j]=miss2; } } // // Determine Groups to be used. // if ( simple_alg == 1 ) { // set group length to 10 : calculate number of groups // and length of last group ngroups=ndpts/10; for (j=0;j<ngroups;j++) glen[j]=10; itemp=ndpts%10; if (itemp != 0) { ngroups++; glen[ngroups-1]=itemp; } } else { // Use Dr. Glahn's algorithm for determining grouping. // kfildo=6; minpk=10; inc=1; maxgrps=(ndpts/minpk)+1; jmin = calloc(maxgrps,sizeof(g2int)); jmax = calloc(maxgrps,sizeof(g2int)); lbit = calloc(maxgrps,sizeof(g2int)); pack_gp(&kfildo,ifld,&ndpts,&missopt,&minpk,&inc,&miss1,&miss2, jmin,jmax,lbit,glen,&maxgrps,&ngroups,&ibit,&jbit, &kbit,&novref,&lbitref,&ier); //printf("SAGier = %d %d %d %d %d %d\n",ier,ibit,jbit,kbit,novref,lbitref); for ( ng=0; ng<ngroups; ng++) glen[ng]=glen[ng]+novref; free(jmin); free(jmax); free(lbit); } // // For each group, find the group's reference value (min) // and the number of bits needed to hold the remaining values // n=0; for ( ng=0; ng<ngroups; ng++) { // how many of each type? num0=num1=num2=0; for (j=n; j<n+glen[ng]; j++) { if (ifldmiss[j] == 0 ) num0++; if (ifldmiss[j] == 1 ) num1++; if (ifldmiss[j] == 2 ) num2++; } if ( num0 == 0 ) { // all missing values if ( num1 == 0 ) { // all secondary missing gref[ng]=-2; gwidth[ng]=0; } else if ( num2 == 0 ) { // all primary missing gref[ng]=-1; gwidth[ng]=0; } else { // both primary and secondary gref[ng]=0; gwidth[ng]=1; } } else { // contains some non-missing data // find max and min values of group gref[ng]=2147483647; imax=-2147483647; j=n; for ( lg=0; lg<glen[ng]; lg++ ) { if ( ifldmiss[j] == 0 ) { if (ifld[j] < gref[ng]) gref[ng]=ifld[j]; if (ifld[j] > imax) imax=ifld[j]; } j++; } if (missopt == 1) imax=imax+1; if (missopt == 2) imax=imax+2; // calc num of bits needed to hold data if ( gref[ng] != imax ) { temp=log((double)(imax-gref[ng]+1))/alog2; gwidth[ng]=(g2int)ceil(temp); } else { gwidth[ng]=0; } } // Subtract min from data j=n; mtemp=(g2int)int_power(2.,gwidth[ng]); for ( lg=0; lg<glen[ng]; lg++ ) { if (ifldmiss[j] == 0) // non-missing ifld[j]=ifld[j]-gref[ng]; else if (ifldmiss[j] == 1) // primary missing ifld[j]=mtemp-1; else if (ifldmiss[j] == 2) // secondary missing ifld[j]=mtemp-2; j++; } // increment fld array counter n=n+glen[ng]; } // // Find max of the group references and calc num of bits needed // to pack each groups reference value, then // pack up group reference values // //printf(" GREFS: "); //for (j=0;j<ngroups;j++) printf(" %d",gref[j]); printf("\n"); igmax=gref[0]; for (j=1;j<ngroups;j++) if (gref[j] > igmax) igmax=gref[j]; if (missopt == 1) igmax=igmax+1; if (missopt == 2) igmax=igmax+2; if (igmax != 0) { temp=log((double)(igmax+1))/alog2; nbitsgref=(g2int)ceil(temp); // reset the ref values of any "missing only" groups. mtemp=(g2int)int_power(2.,nbitsgref); for ( j=0; j<ngroups; j++ ) { if (gref[j] == -1) gref[j]=mtemp-1; if (gref[j] == -2) gref[j]=mtemp-2; } sbits(cpack,gref,iofst,nbitsgref,0,ngroups); itemp=nbitsgref*ngroups; iofst=iofst+itemp; // Pad last octet with Zeros, if necessary, if ( (itemp%8) != 0) { left=8-(itemp%8); sbit(cpack,&zero,iofst,left); iofst=iofst+left; } } else { nbitsgref=0; } // // Find max/min of the group widths and calc num of bits needed // to pack each groups width value, then // pack up group width values // //write(77,*)'GWIDTHS: ',(gwidth(j),j=1,ngroups) iwmax=gwidth[0]; ngwidthref=gwidth[0]; for (j=1;j<ngroups;j++) { if (gwidth[j] > iwmax) iwmax=gwidth[j]; if (gwidth[j] < ngwidthref) ngwidthref=gwidth[j]; } if (iwmax != ngwidthref) { temp=log((double)(iwmax-ngwidthref+1))/alog2; nbitsgwidth=(g2int)ceil(temp); for ( i=0; i<ngroups; i++) gwidth[i]=gwidth[i]-ngwidthref; sbits(cpack,gwidth,iofst,nbitsgwidth,0,ngroups); itemp=nbitsgwidth*ngroups; iofst=iofst+itemp; // Pad last octet with Zeros, if necessary, if ( (itemp%8) != 0) { left=8-(itemp%8); sbit(cpack,&zero,iofst,left); iofst=iofst+left; } } else { nbitsgwidth=0; for (i=0;i<ngroups;i++) gwidth[i]=0; } // // Find max/min of the group lengths and calc num of bits needed // to pack each groups length value, then // pack up group length values // //printf(" GLENS: "); //for (j=0;j<ngroups;j++) printf(" %d",glen[j]); printf("\n"); ilmax=glen[0]; nglenref=glen[0]; for (j=1;j<ngroups-1;j++) { if (glen[j] > ilmax) ilmax=glen[j]; if (glen[j] < nglenref) nglenref=glen[j]; } nglenlast=glen[ngroups-1]; if (ilmax != nglenref) { temp=log((double)(ilmax-nglenref+1))/alog2; nbitsglen=(g2int)ceil(temp); for ( i=0; i<ngroups-1; i++) glen[i]=glen[i]-nglenref; sbits(cpack,glen,iofst,nbitsglen,0,ngroups); itemp=nbitsglen*ngroups; iofst=iofst+itemp; // Pad last octet with Zeros, if necessary, if ( (itemp%8) != 0) { left=8-(itemp%8); sbit(cpack,&zero,iofst,left); iofst=iofst+left; } } else { nbitsglen=0; for (i=0;i<ngroups;i++) glen[i]=0; } // // For each group, pack data values // //write(77,*)'IFLDS: ',(ifld(j),j=1,ndpts) n=0; ij=0; for ( ng=0; ng<ngroups; ng++) { glength=glen[ng]+nglenref; if (ng == (ngroups-1) ) glength=nglenlast; grpwidth=gwidth[ng]+ngwidthref; //write(77,*)'NGP ',ng,grpwidth,glength,gref(ng) if ( grpwidth != 0 ) { sbits(cpack,ifld+n,iofst,grpwidth,0,glength); iofst=iofst+(grpwidth*glength); } // do kk=1,glength // ij=ij+1 //write(77,*)'SAG ',ij,fld(ij),ifld(ij),gref(ng),bscale,rmin,dscale // enddo n=n+glength; } // Pad last octet with Zeros, if necessary, if ( (iofst%8) != 0) { left=8-(iofst%8); sbit(cpack,&zero,iofst,left); iofst=iofst+left; } *lcpack=iofst/8; // if ( ifld != 0 ) free(ifld); if ( jfld != 0 ) free(jfld); if ( ifldmiss != 0 ) free(ifldmiss); if ( gref != 0 ) free(gref); if ( gwidth != 0 ) free(gwidth); if ( glen != 0 ) free(glen); //} //else { // Constant field ( max = min ) // nbits=0; // *lcpack=0; // nbitsgref=0; // ngroups=0; //} // // Fill in ref value and number of bits in Template 5.2 // mkieee(&rmin,idrstmpl+0,1); // ensure reference value is IEEE format idrstmpl[3]=nbitsgref; idrstmpl[4]=0; // original data were reals idrstmpl[5]=1; // general group splitting idrstmpl[9]=ngroups; // Number of groups idrstmpl[10]=ngwidthref; // reference for group widths idrstmpl[11]=nbitsgwidth; // num bits used for group widths idrstmpl[12]=nglenref; // Reference for group lengths idrstmpl[13]=1; // length increment for group lengths idrstmpl[14]=nglenlast; // True length of last group idrstmpl[15]=nbitsglen; // num bits used for group lengths if (idrsnum == 3) { idrstmpl[17]=nbitsd/8; // num bits used for extra spatial // differencing values } } g2clib-1.6.0/mkieee.c0000755002373300042670000000574412522400361014136 0ustar Boi.Vuongglobal#include <stdlib.h> #include <math.h> #include "grib2.h" void mkieee(g2float *a,g2int *rieee,g2int num) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: mkieee // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-29 // // ABSTRACT: This subroutine stores a list of real values in // 32-bit IEEE floating point format. // // PROGRAM HISTORY LOG: // 2002-10-29 Gilbert // // USAGE: mkieee(g2float *a,g2int *rieee,g2int num); // INPUT ARGUMENT LIST: // a - Input array of floating point values. // num - Number of floating point values to convert. // // OUTPUT ARGUMENT LIST: // rieee - Output array of data values in 32-bit IEEE format // stored in g2int integer array. rieee must be allocated // with at least 4*num bytes of memory before calling this // function. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$ { g2int j,n,ieee,iexp,imant; double alog2,atemp; static double two23,two126; static g2int test=0; //g2intu msk1=0x80000000; // 10000000000000000000000000000000 binary //g2int msk2=0x7F800000; // 01111111100000000000000000000000 binary //g2int msk3=0x007FFFFF; // 00000000011111111111111111111111 binary if ( test == 0 ) { two23=(double)int_power(2.0,23); two126=(double)int_power(2.0,126); test=1; } alog2=0.69314718; // ln(2.0) for (j=0;j<num;j++) { ieee=0; if (a[j] == 0.0) { rieee[j]=ieee; continue; } // // Set Sign bit (bit 31 - leftmost bit) // if (a[j] < 0.0) { ieee= 1 << 31; atemp=-1.0*a[j]; } else { ieee= 0 << 31; atemp=a[j]; } //printf("sign %ld %x \n",ieee,ieee); // // Determine exponent n with base 2 // if ( atemp >= 1.0 ) { n = 0; while ( int_power(2.0,n+1) <= atemp ) { n++; } } else { n = -1; while ( int_power(2.0,n) > atemp ) { n--; } } //n=(g2int)floor(log(atemp)/alog2); iexp=n+127; if (n > 127) iexp=255; // overflow if (n < -127) iexp=0; //printf("exp %ld %ld \n",iexp,n); // set exponent bits ( bits 30-23 ) ieee = ieee | ( iexp << 23 ); // // Determine Mantissa // if (iexp != 255) { if (iexp != 0) atemp=(atemp/int_power(2.0,n))-1.0; else atemp=atemp*two126; imant=(g2int)rint(atemp*two23); } else { imant=0; } //printf("mant %ld %x \n",imant,imant); // set mantissa bits ( bits 22-0 ) ieee = ieee | imant; // // Transfer IEEE bit string to rieee array // rieee[j]=ieee; } return; } g2clib-1.6.0/pack_gp.c0000644002373300042670000013315412522400361014275 0ustar Boi.Vuongglobal/* pack_gp.f -- translated by f2c (version 20031025). You must link the resulting object file with libf2c: on Microsoft Windows system, link with libf2c.lib; on Linux or Unix systems, link with .../path/to/libf2c.a -lm or, if you install libf2c.a in a standard place, with -lf2c -lm -- in that order, at the end of the command line, as in cc *.o -lf2c -lm Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., http://www.netlib.org/f2c/libf2c.zip */ /*#include "f2c.h"*/ #include <stdlib.h> #include "grib2.h" typedef g2int integer; typedef g2int logical; #define TRUE_ (1) #define FALSE_ (0) /* Subroutine */ int pack_gp(integer *kfildo, integer *ic, integer *nxy, integer *is523, integer *minpk, integer *inc, integer *missp, integer *misss, integer *jmin, integer *jmax, integer *lbit, integer *nov, integer *ndg, integer *lx, integer *ibit, integer *jbit, integer * kbit, integer *novref, integer *lbitref, integer *ier) { /* Initialized data */ const integer mallow = 1073741825; /* MALLOW=2**30+1 */ static integer ifeed = 12; static integer ifirst = 0; /* System generated locals */ integer i__1, i__2, i__3; /* Local variables */ static integer j, k, l; static logical adda; static integer ired, kinc, mina, maxa, minb, maxb, minc, maxc, ibxx2[31]; static char cfeed[1]; static integer nenda, nendb, ibita, ibitb, minak, minbk, maxak, maxbk, minck, maxck, nouta, lmiss, itest, nount; extern /* Subroutine */ int reduce(integer *, integer *, integer *, integer *, integer *, integer *, integer *, integer *, integer *, integer *, integer *, integer *, integer *); static integer ibitbs, mislla, misllb, misllc, iersav, lminpk, ktotal, kounta, kountb, kstart, mstart, mintst, maxtst, kounts, mintstk, maxtstk; integer *misslx; /* FEBRUARY 1994 GLAHN TDL MOS-2000 */ /* JUNE 1995 GLAHN MODIFIED FOR LMISS ERROR. */ /* JULY 1996 GLAHN ADDED MISSS */ /* FEBRUARY 1997 GLAHN REMOVED 4 REDUNDANT TESTS FOR */ /* MISSP.EQ.0; INSERTED A TEST TO BETTER */ /* HANDLE A STRING OF 9999'S */ /* FEBRUARY 1997 GLAHN ADDED LOOPS TO ELIMINATE TEST FOR */ /* MISSS WHEN MISSS = 0 */ /* MARCH 1997 GLAHN CORRECTED FOR SECONDARY MISSING VALUE */ /* MARCH 1997 GLAHN CORRECTED FOR USE OF LOCAL VALUE */ /* OF MINPK */ /* MARCH 1997 GLAHN CORRECTED FOR SECONDARY MISSING VALUE */ /* MARCH 1997 GLAHN CHANGED CALCULATING NUMBER OF BITS */ /* THROUGH EXPONENTS TO AN ARRAY (IMPROVED */ /* OVERALL PACKING PERFORMANCE BY ABOUT */ /* 35 PERCENT!). ALLOWED 0 BITS FOR */ /* PACKING JMIN( ), LBIT( ), AND NOV( ). */ /* MAY 1997 GLAHN A NUMBER OF CHANGES FOR EFFICIENCY. */ /* MOD FUNCTIONS ELIMINATED AND ONE */ /* IFTHEN ADDED. JOUNT REMOVED. */ /* RECOMPUTATION OF BITS NOT MADE UNLESS */ /* NECESSARY AFTER MOVING POINTS FROM */ /* ONE GROUP TO ANOTHER. NENDB ADJUSTED */ /* TO ELIMINATE POSSIBILITY OF VERY */ /* SMALL GROUP AT THE END. */ /* ABOUT 8 PERCENT IMPROVEMENT IN */ /* OVERALL PACKING. ISKIPA REMOVED; */ /* THERE IS ALWAYS A GROUP B THAT CAN */ /* BECOME GROUP A. CONTROL ON SIZE */ /* OF GROUP B (STATEMENT BELOW 150) */ /* ADDED. ADDED ADDA, AND USE */ /* OF GE AND LE INSTEAD OF GT AND LT */ /* IN LOOPS BETWEEN 150 AND 160. */ /* IBITBS ADDED TO SHORTEN TRIPS */ /* THROUGH LOOP. */ /* MARCH 2000 GLAHN MODIFIED FOR GRIB2; CHANGED NAME FROM */ /* PACKGP */ /* JANUARY 2001 GLAHN COMMENTS; IER = 706 SUBSTITUTED FOR */ /* STOPS; ADDED RETURN1; REMOVED STATEMENT */ /* NUMBER 110; ADDED IER AND * RETURN */ /* NOVEMBER 2001 GLAHN CHANGED SOME DIAGNOSTIC FORMATS TO */ /* ALLOW PRINTING LARGER NUMBERS */ /* NOVEMBER 2001 GLAHN ADDED MISSLX( ) TO PUT MAXIMUM VALUE */ /* INTO JMIN( ) WHEN ALL VALUES MISSING */ /* TO AGREE WITH GRIB STANDARD. */ /* NOVEMBER 2001 GLAHN CHANGED TWO TESTS ON MISSP AND MISSS */ /* EQ 0 TO TESTS ON IS523. HOWEVER, */ /* MISSP AND MISSS CANNOT IN GENERAL BE */ /* = 0. */ /* NOVEMBER 2001 GLAHN ADDED CALL TO REDUCE; DEFINED ITEST */ /* BEFORE LOOPS TO REDUCE COMPUTATION; */ /* STARTED LARGE GROUP WHEN ALL SAME */ /* VALUE */ /* DECEMBER 2001 GLAHN MODIFIED AND ADDED A FEW COMMENTS */ /* JANUARY 2002 GLAHN REMOVED LOOP BEFORE 150 TO DETERMINE */ /* A GROUP OF ALL SAME VALUE */ /* JANUARY 2002 GLAHN CHANGED MALLOW FROM 9999999 TO 2**30+1, */ /* AND MADE IT A PARAMETER */ /* MARCH 2002 GLAHN ADDED NON FATAL IER = 716, 717; */ /* REMOVED NENDB=NXY ABOVE 150; */ /* ADDED IERSAV=0; COMMENTS */ /* PURPOSE */ /* DETERMINES GROUPS OF VARIABLE SIZE, BUT AT LEAST OF */ /* SIZE MINPK, THE ASSOCIATED MAX (JMAX( )) AND MIN (JMIN( )), */ /* THE NUMBER OF BITS NECESSARY TO HOLD THE VALUES IN EACH */ /* GROUP (LBIT( )), THE NUMBER OF VALUES IN EACH GROUP */ /* (NOV( )), THE NUMBER OF BITS NECESSARY TO PACK THE JMIN( ) */ /* VALUES (IBIT), THE NUMBER OF BITS NECESSARY TO PACK THE */ /* LBIT( ) VALUES (JBIT), AND THE NUMBER OF BITS NECESSARY */ /* TO PACK THE NOV( ) VALUES (KBIT). THE ROUTINE IS DESIGNED */ /* TO DETERMINE THE GROUPS SUCH THAT A SMALL NUMBER OF BITS */ /* IS NECESSARY TO PACK THE DATA WITHOUT EXCESSIVE */ /* COMPUTATIONS. IF ALL VALUES IN THE GROUP ARE ZERO, THE */ /* NUMBER OF BITS TO USE IN PACKING IS DEFINED AS ZERO WHEN */ /* THERE CAN BE NO MISSING VALUES; WHEN THERE CAN BE MISSING */ /* VALUES, THE NUMBER OF BITS MUST BE AT LEAST 1 TO HAVE */ /* THE CAPABILITY TO RECOGNIZE THE MISSING VALUE. HOWEVER, */ /* IF ALL VALUES IN A GROUP ARE MISSING, THE NUMBER OF BITS */ /* NEEDED IS 0, AND THE UNPACKER RECOGNIZES THIS. */ /* ALL VARIABLES ARE INTEGER. EVEN THOUGH THE GROUPS ARE */ /* INITIALLY OF SIZE MINPK OR LARGER, AN ADJUSTMENT BETWEEN */ /* TWO GROUPS (THE LOOKBACK PROCEDURE) MAY MAKE A GROUP */ /* SMALLER THAN MINPK. THE CONTROL ON GROUP SIZE IS THAT */ /* THE SUM OF THE SIZES OF THE TWO CONSECUTIVE GROUPS, EACH OF */ /* SIZE MINPK OR LARGER, IS NOT DECREASED. WHEN DETERMINING */ /* THE NUMBER OF BITS NECESSARY FOR PACKING, THE LARGEST */ /* VALUE THAT CAN BE ACCOMMODATED IN, SAY, MBITS, IS */ /* 2**MBITS-1; THIS LARGEST VALUE (AND THE NEXT SMALLEST */ /* VALUE) IS RESERVED FOR THE MISSING VALUE INDICATOR (ONLY) */ /* WHEN IS523 NE 0. IF THE DIMENSION NDG */ /* IS NOT LARGE ENOUGH TO HOLD ALL THE GROUPS, THE LOCAL VALUE */ /* OF MINPK IS INCREASED BY 50 PERCENT. THIS IS REPEATED */ /* UNTIL NDG WILL SUFFICE. A DIAGNOSTIC IS PRINTED WHENEVER */ /* THIS HAPPENS, WHICH SHOULD BE VERY RARELY. IF IT HAPPENS */ /* OFTEN, NDG IN SUBROUTINE PACK SHOULD BE INCREASED AND */ /* A CORRESPONDING INCREASE IN SUBROUTINE UNPACK MADE. */ /* CONSIDERABLE CODE IS PROVIDED SO THAT NO MORE CHECKING */ /* FOR MISSING VALUES WITHIN LOOPS IS DONE THAN NECESSARY; */ /* THE ADDED EFFICIENCY OF THIS IS RELATIVELY MINOR, */ /* BUT DOES NO HARM. FOR GRIB2, THE REFERENCE VALUE FOR */ /* THE LENGTH OF GROUPS IN NOV( ) AND FOR THE NUMBER OF */ /* BITS NECESSARY TO PACK GROUP VALUES ARE DETERMINED, */ /* AND SUBTRACTED BEFORE JBIT AND KBIT ARE DETERMINED. */ /* WHEN 1 OR MORE GROUPS ARE LARGE COMPARED TO THE OTHERS, */ /* THE WIDTH OF ALL GROUPS MUST BE AS LARGE AS THE LARGEST. */ /* A SUBROUTINE REDUCE BREAKS UP LARGE GROUPS INTO 2 OR */ /* MORE TO REDUCE TOTAL BITS REQUIRED. IF REDUCE SHOULD */ /* ABORT, PACK_GP WILL BE EXECUTED AGAIN WITHOUT THE CALL */ /* TO REDUCE. */ /* DATA SET USE */ /* KFILDO - UNIT NUMBER FOR OUTPUT (PRINT) FILE. (OUTPUT) */ /* VARIABLES IN CALL SEQUENCE */ /* KFILDO = UNIT NUMBER FOR OUTPUT (PRINT) FILE. (INPUT) */ /* IC( ) = ARRAY TO HOLD DATA FOR PACKING. THE VALUES */ /* DO NOT HAVE TO BE POSITIVE AT THIS POINT, BUT */ /* MUST BE IN THE RANGE -2**30 TO +2**30 (THE */ /* THE VALUE OF MALLOW). THESE INTEGER VALUES */ /* WILL BE RETAINED EXACTLY THROUGH PACKING AND */ /* UNPACKING. (INPUT) */ /* NXY = NUMBER OF VALUES IN IC( ). ALSO TREATED */ /* AS ITS DIMENSION. (INPUT) */ /* IS523 = missing value management */ /* 0=data contains no missing values */ /* 1=data contains Primary missing values */ /* 2=data contains Primary and secondary missing values */ /* (INPUT) */ /* MINPK = THE MINIMUM SIZE OF EACH GROUP, EXCEPT POSSIBLY */ /* THE LAST ONE. (INPUT) */ /* INC = THE NUMBER OF VALUES TO ADD TO AN ALREADY */ /* EXISTING GROUP IN DETERMINING WHETHER OR NOT */ /* TO START A NEW GROUP. IDEALLY, THIS WOULD BE */ /* 1, BUT EACH TIME INC VALUES ARE ATTEMPTED, THE */ /* MAX AND MIN OF THE NEXT MINPK VALUES MUST BE */ /* FOUND. THIS IS "A LOOP WITHIN A LOOP," AND */ /* A SLIGHTLY LARGER VALUE MAY GIVE ABOUT AS GOOD */ /* RESULTS WITH SLIGHTLY LESS COMPUTATIONAL TIME. */ /* IF INC IS LE 0, 1 IS USED, AND A DIAGNOSTIC IS */ /* OUTPUT. NOTE: IT IS EXPECTED THAT INC WILL */ /* EQUAL 1. THE CODE USES INC PRIMARILY IN THE */ /* LOOPS STARTING AT STATEMENT 180. IF INC */ /* WERE 1, THERE WOULD NOT NEED TO BE LOOPS */ /* AS SUCH. HOWEVER, KINC (THE LOCAL VALUE OF */ /* INC) IS SET GE 1 WHEN NEAR THE END OF THE DATA */ /* TO FORESTALL A VERY SMALL GROUP AT THE END. */ /* (INPUT) */ /* MISSP = WHEN MISSING POINTS CAN BE PRESENT IN THE DATA, */ /* THEY WILL HAVE THE VALUE MISSP OR MISSS. */ /* MISSP IS THE PRIMARY MISSING VALUE AND MISSS */ /* IS THE SECONDARY MISSING VALUE . THESE MUST */ /* NOT BE VALUES THAT WOULD OCCUR WITH SUBTRACTING */ /* THE MINIMUM (REFERENCE) VALUE OR SCALING. */ /* FOR EXAMPLE, MISSP = 0 WOULD NOT BE ADVISABLE. */ /* (INPUT) */ /* MISSS = SECONDARY MISSING VALUE INDICATOR (SEE MISSP). */ /* (INPUT) */ /* JMIN(J) = THE MINIMUM OF EACH GROUP (J=1,LX). (OUTPUT) */ /* JMAX(J) = THE MAXIMUM OF EACH GROUP (J=1,LX). THIS IS */ /* NOT REALLY NEEDED, BUT SINCE THE MAX OF EACH */ /* GROUP MUST BE FOUND, SAVING IT HERE IS CHEAP */ /* IN CASE THE USER WANTS IT. (OUTPUT) */ /* LBIT(J) = THE NUMBER OF BITS NECESSARY TO PACK EACH GROUP */ /* (J=1,LX). IT IS ASSUMED THE MINIMUM OF EACH */ /* GROUP WILL BE REMOVED BEFORE PACKING, AND THE */ /* VALUES TO PACK WILL, THEREFORE, ALL BE POSITIVE. */ /* HOWEVER, IC( ) DOES NOT NECESSARILY CONTAIN */ /* ALL POSITIVE VALUES. IF THE OVERALL MINIMUM */ /* HAS BEEN REMOVED (THE USUAL CASE), THEN IC( ) */ /* WILL CONTAIN ONLY POSITIVE VALUES. (OUTPUT) */ /* NOV(J) = THE NUMBER OF VALUES IN EACH GROUP (J=1,LX). */ /* (OUTPUT) */ /* NDG = THE DIMENSION OF JMIN( ), JMAX( ), LBIT( ), AND */ /* NOV( ). (INPUT) */ /* LX = THE NUMBER OF GROUPS DETERMINED. (OUTPUT) */ /* IBIT = THE NUMBER OF BITS NECESSARY TO PACK THE JMIN(J) */ /* VALUES, J=1,LX. (OUTPUT) */ /* JBIT = THE NUMBER OF BITS NECESSARY TO PACK THE LBIT(J) */ /* VALUES, J=1,LX. (OUTPUT) */ /* KBIT = THE NUMBER OF BITS NECESSARY TO PACK THE NOV(J) */ /* VALUES, J=1,LX. (OUTPUT) */ /* NOVREF = REFERENCE VALUE FOR NOV( ). (OUTPUT) */ /* LBITREF = REFERENCE VALUE FOR LBIT( ). (OUTPUT) */ /* IER = ERROR RETURN. */ /* 706 = VALUE WILL NOT PACK IN 30 BITS--FATAL */ /* 714 = ERROR IN REDUCE--NON-FATAL */ /* 715 = NGP NOT LARGE ENOUGH IN REDUCE--NON-FATAL */ /* 716 = MINPK INCEASED--NON-FATAL */ /* 717 = INC SET = 1--NON-FATAL */ /* (OUTPUT) */ /* * = ALTERNATE RETURN WHEN IER NE 0 AND FATAL ERROR. */ /* INTERNAL VARIABLES */ /* CFEED = CONTAINS THE CHARACTER REPRESENTATION */ /* OF A PRINTER FORM FEED. */ /* IFEED = CONTAINS THE INTEGER VALUE OF A PRINTER */ /* FORM FEED. */ /* KINC = WORKING COPY OF INC. MAY BE MODIFIED. */ /* MINA = MINIMUM VALUE IN GROUP A. */ /* MAXA = MAXIMUM VALUE IN GROUP A. */ /* NENDA = THE PLACE IN IC( ) WHERE GROUP A ENDS. */ /* KSTART = THE PLACE IN IC( ) WHERE GROUP A STARTS. */ /* IBITA = NUMBER OF BITS NEEDED TO HOLD VALUES IN GROUP A. */ /* MINB = MINIMUM VALUE IN GROUP B. */ /* MAXB = MAXIMUM VALUE IN GROUP B. */ /* NENDB = THE PLACE IN IC( ) WHERE GROUP B ENDS. */ /* IBITB = NUMBER OF BITS NEEDED TO HOLD VALUES IN GROUP B. */ /* MINC = MINIMUM VALUE IN GROUP C. */ /* MAXC = MAXIMUM VALUE IN GROUP C. */ /* KTOTAL = COUNT OF NUMBER OF VALUES IN IC( ) PROCESSED. */ /* NOUNT = NUMBER OF VALUES ADDED TO GROUP A. */ /* LMISS = 0 WHEN IS523 = 0. WHEN PACKING INTO A */ /* SPECIFIC NUMBER OF BITS, SAY MBITS, */ /* THE MAXIMUM VALUE THAT CAN BE HANDLED IS */ /* 2**MBITS-1. WHEN IS523 = 1, INDICATING */ /* PRIMARY MISSING VALUES, THIS MAXIMUM VALUE */ /* IS RESERVED TO HOLD THE PRIMARY MISSING VALUE */ /* INDICATOR AND LMISS = 1. WHEN IS523 = 2, */ /* THE VALUE JUST BELOW THE MAXIMUM (I.E., */ /* 2**MBITS-2) IS RESERVED TO HOLD THE SECONDARY */ /* MISSING VALUE INDICATOR AND LMISS = 2. */ /* LMINPK = LOCAL VALUE OF MINPK. THIS WILL BE ADJUSTED */ /* UPWARD WHENEVER NDG IS NOT LARGE ENOUGH TO HOLD */ /* ALL THE GROUPS. */ /* MALLOW = THE LARGEST ALLOWABLE VALUE FOR PACKING. */ /* MISLLA = SET TO 1 WHEN ALL VALUES IN GROUP A ARE MISSING. */ /* THIS IS USED TO DISTINGUISH BETWEEN A REAL */ /* MINIMUM WHEN ALL VALUES ARE NOT MISSING */ /* AND A MINIMUM THAT HAS BEEN SET TO ZERO WHEN */ /* ALL VALUES ARE MISSING. 0 OTHERWISE. */ /* NOTE THAT THIS DOES NOT DISTINGUISH BETWEEN */ /* PRIMARY AND SECONDARY MISSINGS WHEN SECONDARY */ /* MISSINGS ARE PRESENT. THIS MEANS THAT */ /* LBIT( ) WILL NOT BE ZERO WITH THE RESULTING */ /* COMPRESSION EFFICIENCY WHEN SECONDARY MISSINGS */ /* ARE PRESENT. ALSO NOTE THAT A CHECK HAS BEEN */ /* MADE EARLIER TO DETERMINE THAT SECONDARY */ /* MISSINGS ARE REALLY THERE. */ /* MISLLB = SET TO 1 WHEN ALL VALUES IN GROUP B ARE MISSING. */ /* THIS IS USED TO DISTINGUISH BETWEEN A REAL */ /* MINIMUM WHEN ALL VALUES ARE NOT MISSING */ /* AND A MINIMUM THAT HAS BEEN SET TO ZERO WHEN */ /* ALL VALUES ARE MISSING. 0 OTHERWISE. */ /* MISLLC = PERFORMS THE SAME FUNCTION FOR GROUP C THAT */ /* MISLLA AND MISLLB DO FOR GROUPS B AND C, */ /* RESPECTIVELY. */ /* IBXX2(J) = AN ARRAY THAT WHEN THIS ROUTINE IS FIRST ENTERED */ /* IS SET TO 2**J, J=0,30. IBXX2(30) = 2**30, WHICH */ /* IS THE LARGEST VALUE PACKABLE, BECAUSE 2**31 */ /* IS LARGER THAN THE INTEGER WORD SIZE. */ /* IFIRST = SET BY DATA STATEMENT TO 0. CHANGED TO 1 ON */ /* FIRST */ /* ENTRY WHEN IBXX2( ) IS FILLED. */ /* MINAK = KEEPS TRACK OF THE LOCATION IN IC( ) WHERE THE */ /* MINIMUM VALUE IN GROUP A IS LOCATED. */ /* MAXAK = DOES THE SAME AS MINAK, EXCEPT FOR THE MAXIMUM. */ /* MINBK = THE SAME AS MINAK FOR GROUP B. */ /* MAXBK = THE SAME AS MAXAK FOR GROUP B. */ /* MINCK = THE SAME AS MINAK FOR GROUP C. */ /* MAXCK = THE SAME AS MAXAK FOR GROUP C. */ /* ADDA = KEEPS TRACK WHETHER OR NOT AN ATTEMPT TO ADD */ /* POINTS TO GROUP A WAS MADE. IF SO, THEN ADDA */ /* KEEPS FROM TRYING TO PUT ONE BACK INTO B. */ /* (LOGICAL) */ /* IBITBS = KEEPS CURRENT VALUE IF IBITB SO THAT LOOP */ /* ENDING AT 166 DOESN'T HAVE TO START AT */ /* IBITB = 0 EVERY TIME. */ /* MISSLX(J) = MALLOW EXCEPT WHEN A GROUP IS ALL ONE VALUE (AND */ /* LBIT(J) = 0) AND THAT VALUE IS MISSING. IN */ /* THAT CASE, MISSLX(J) IS MISSP OR MISSS. THIS */ /* GETS INSERTED INTO JMIN(J) LATER AS THE */ /* MISSING INDICATOR; IT CAN'T BE PUT IN UNTIL */ /* THE END, BECAUSE JMIN( ) IS USED TO CALCULATE */ /* THE MAXIMUM NUMBER OF BITS (IBITS) NEEDED TO */ /* PACK JMIN( ). */ /* 1 2 3 4 5 6 7 X */ /* NON SYSTEM SUBROUTINES CALLED */ /* NONE */ /* MISSLX( ) was AN AUTOMATIC ARRAY. */ misslx = (integer *)calloc(*ndg,sizeof(integer)); /* Parameter adjustments */ --ic; --nov; --lbit; --jmax; --jmin; /* Function Body */ *ier = 0; iersav = 0; /* CALL TIMPR(KFILDO,KFILDO,'START PACK_GP ') */ *(unsigned char *)cfeed = (char) ifeed; ired = 0; /* IRED IS A FLAG. WHEN ZERO, REDUCE WILL BE CALLED. */ /* IF REDUCE ABORTS, IRED = 1 AND IS NOT CALLED. IN */ /* THIS CASE PACK_GP EXECUTES AGAIN EXCEPT FOR REDUCE. */ if (*inc <= 0) { iersav = 717; /* WRITE(KFILDO,101)INC */ /* 101 FORMAT(/' ****INC ='I8,' NOT CORRECT IN PACK_GP. 1 IS USED.') */ } /* THERE WILL BE A RESTART OF PACK_GP IF SUBROUTINE REDUCE */ /* ABORTS. THIS SHOULD NOT HAPPEN, BUT IF IT DOES, PACK_GP */ /* WILL COMPLETE WITHOUT SUBROUTINE REDUCE. A NON FATAL */ /* DIAGNOSTIC RETURN IS PROVIDED. */ L102: /*kinc = max(*inc,1);*/ kinc = (*inc > 1) ? *inc : 1; lminpk = *minpk; /* CALCULATE THE POWERS OF 2 THE FIRST TIME ENTERED. */ if (ifirst == 0) { ifirst = 1; ibxx2[0] = 1; for (j = 1; j <= 30; ++j) { ibxx2[j] = ibxx2[j - 1] << 1; /* L104: */ } } /* THERE WILL BE A RESTART AT 105 IS NDG IS NOT LARGE ENOUGH. */ /* A NON FATAL DIAGNOSTIC RETURN IS PROVIDED. */ L105: kstart = 1; ktotal = 0; *lx = 0; adda = FALSE_; lmiss = 0; if (*is523 == 1) { lmiss = 1; } if (*is523 == 2) { lmiss = 2; } /* ************************************* */ /* THIS SECTION COMPUTES STATISTICS FOR GROUP A. GROUP A IS */ /* A GROUP OF SIZE LMINPK. */ /* ************************************* */ ibita = 0; mina = mallow; maxa = -mallow; minak = mallow; maxak = -mallow; /* FIND THE MIN AND MAX OF GROUP A. THIS WILL INITIALLY BE OF */ /* SIZE LMINPK (IF THERE ARE STILL LMINPK VALUES IN IC( )), BUT */ /* WILL INCREASE IN SIZE IN INCREMENTS OF INC UNTIL A NEW */ /* GROUP IS STARTED. THE DEFINITION OF GROUP A IS DONE HERE */ /* ONLY ONCE (UPON INITIAL ENTRY), BECAUSE A GROUP B CAN ALWAYS */ /* BECOME A NEW GROUP A AFTER A IS PACKED, EXCEPT IF LMINPK */ /* HAS TO BE INCREASED BECAUSE NDG IS TOO SMALL. THEREFORE, */ /* THE SEPARATE LOOPS FOR MISSING AND NON-MISSING HERE BUYS */ /* ALMOST NOTHING. */ /* Computing MIN */ i__1 = kstart + lminpk - 1; /*nenda = min(i__1,*nxy);*/ nenda = (i__1 < *nxy) ? i__1 : *nxy; if (*nxy - nenda <= lminpk / 2) { nenda = *nxy; } /* ABOVE STATEMENT GUARANTEES THE LAST GROUP IS GT LMINPK/2 BY */ /* MAKING THE ACTUAL GROUP LARGER. IF A PROVISION LIKE THIS IS */ /* NOT INCLUDED, THERE WILL MANY TIMES BE A VERY SMALL GROUP */ /* AT THE END. USE SEPARATE LOOPS FOR MISSING AND NO MISSING */ /* VALUES FOR EFFICIENCY. */ /* DETERMINE WHETHER THERE IS A LONG STRING OF THE SAME VALUE */ /* UNLESS NENDA = NXY. THIS MAY ALLOW A LARGE GROUP A TO */ /* START WITH, AS WITH MISSING VALUES. SEPARATE LOOPS FOR */ /* MISSING OPTIONS. THIS SECTION IS ONLY EXECUTED ONCE, */ /* IN DETERMINING THE FIRST GROUP. IT HELPS FOR AN ARRAY */ /* OF MOSTLY MISSING VALUES OR OF ONE VALUE, SUCH AS */ /* RADAR OR PRECIP DATA. */ if (nenda != *nxy && ic[kstart] == ic[kstart + 1]) { /* NO NEED TO EXECUTE IF FIRST TWO VALUES ARE NOT EQUAL. */ if (*is523 == 0) { /* THIS LOOP IS FOR NO MISSING VALUES. */ i__1 = *nxy; for (k = kstart + 1; k <= i__1; ++k) { if (ic[k] != ic[kstart]) { /* Computing MAX */ i__2 = nenda, i__3 = k - 1; /*nenda = max(i__2,i__3);*/ nenda = (i__2 > i__3) ? i__2 : i__3; goto L114; } /* L111: */ } nenda = *nxy; /* FALL THROUGH THE LOOP MEANS ALL VALUES ARE THE SAME. */ } else if (*is523 == 1) { /* THIS LOOP IS FOR PRIMARY MISSING VALUES ONLY. */ i__1 = *nxy; for (k = kstart + 1; k <= i__1; ++k) { if (ic[k] != *missp) { if (ic[k] != ic[kstart]) { /* Computing MAX */ i__2 = nenda, i__3 = k - 1; /*nenda = max(i__2,i__3);*/ nenda = (i__2 > i__3) ? i__2 : i__3; goto L114; } } /* L112: */ } nenda = *nxy; /* FALL THROUGH THE LOOP MEANS ALL VALUES ARE THE SAME. */ } else { /* THIS LOOP IS FOR PRIMARY AND SECONDARY MISSING VALUES. */ i__1 = *nxy; for (k = kstart + 1; k <= i__1; ++k) { if (ic[k] != *missp && ic[k] != *misss) { if (ic[k] != ic[kstart]) { /* Computing MAX */ i__2 = nenda, i__3 = k - 1; /*nenda = max(i__2,i__3);*/ nenda = (i__2 > i__3) ? i__2 : i__3; goto L114; } } /* L113: */ } nenda = *nxy; /* FALL THROUGH THE LOOP MEANS ALL VALUES ARE THE SAME. */ } } L114: if (*is523 == 0) { i__1 = nenda; for (k = kstart; k <= i__1; ++k) { if (ic[k] < mina) { mina = ic[k]; minak = k; } if (ic[k] > maxa) { maxa = ic[k]; maxak = k; } /* L115: */ } } else if (*is523 == 1) { i__1 = nenda; for (k = kstart; k <= i__1; ++k) { if (ic[k] == *missp) { goto L117; } if (ic[k] < mina) { mina = ic[k]; minak = k; } if (ic[k] > maxa) { maxa = ic[k]; maxak = k; } L117: ; } } else { i__1 = nenda; for (k = kstart; k <= i__1; ++k) { if (ic[k] == *missp || ic[k] == *misss) { goto L120; } if (ic[k] < mina) { mina = ic[k]; minak = k; } if (ic[k] > maxa) { maxa = ic[k]; maxak = k; } L120: ; } } kounta = nenda - kstart + 1; /* INCREMENT KTOTAL AND FIND THE BITS NEEDED TO PACK THE A GROUP. */ ktotal += kounta; mislla = 0; if (mina != mallow) { goto L125; } /* ALL MISSING VALUES MUST BE ACCOMMODATED. */ mina = 0; maxa = 0; mislla = 1; ibitb = 0; if (*is523 != 2) { goto L130; } /* WHEN ALL VALUES ARE MISSING AND THERE ARE NO */ /* SECONDARY MISSING VALUES, IBITA = 0. */ /* OTHERWISE, IBITA MUST BE CALCULATED. */ L125: itest = maxa - mina + lmiss; for (ibita = 0; ibita <= 30; ++ibita) { if (itest < ibxx2[ibita]) { goto L130; } /* *** THIS TEST IS THE SAME AS: */ /* *** IF(MAXA-MINA.LT.IBXX2(IBITA)-LMISS)GO TO 130 */ /* L126: */ } /* WRITE(KFILDO,127)MAXA,MINA */ /* 127 FORMAT(' ****ERROR IN PACK_GP. VALUE WILL NOT PACK IN 30 BITS.', */ /* 1 ' MAXA ='I13,' MINA ='I13,'. ERROR AT 127.') */ *ier = 706; goto L900; L130: /* ***D WRITE(KFILDO,131)KOUNTA,KTOTAL,MINA,MAXA,IBITA,MISLLA */ /* ***D131 FORMAT(' AT 130, KOUNTA ='I8,' KTOTAL ='I8,' MINA ='I8, */ /* ***D 1 ' MAXA ='I8,' IBITA ='I3,' MISLLA ='I3) */ L133: if (ktotal >= *nxy) { goto L200; } /* ************************************* */ /* THIS SECTION COMPUTES STATISTICS FOR GROUP B. GROUP B IS A */ /* GROUP OF SIZE LMINPK IMMEDIATELY FOLLOWING GROUP A. */ /* ************************************* */ L140: minb = mallow; maxb = -mallow; minbk = mallow; maxbk = -mallow; ibitbs = 0; mstart = ktotal + 1; /* DETERMINE WHETHER THERE IS A LONG STRING OF THE SAME VALUE. */ /* THIS WORKS WHEN THERE ARE NO MISSING VALUES. */ nendb = 1; if (mstart < *nxy) { if (*is523 == 0) { /* THIS LOOP IS FOR NO MISSING VALUES. */ i__1 = *nxy; for (k = mstart + 1; k <= i__1; ++k) { if (ic[k] != ic[mstart]) { nendb = k - 1; goto L150; } /* L145: */ } nendb = *nxy; /* FALL THROUGH THE LOOP MEANS ALL REMAINING VALUES */ /* ARE THE SAME. */ } } L150: /* Computing MAX */ /* Computing MIN */ i__3 = ktotal + lminpk; /*i__1 = nendb, i__2 = min(i__3,*nxy);*/ i__1 = nendb, i__2 = (i__3 < *nxy) ? i__3 : *nxy; /*nendb = max(i__1,i__2);*/ nendb = (i__1 > i__2) ? i__1 : i__2; /* **** 150 NENDB=MIN(KTOTAL+LMINPK,NXY) */ if (*nxy - nendb <= lminpk / 2) { nendb = *nxy; } /* ABOVE STATEMENT GUARANTEES THE LAST GROUP IS GT LMINPK/2 BY */ /* MAKING THE ACTUAL GROUP LARGER. IF A PROVISION LIKE THIS IS */ /* NOT INCLUDED, THERE WILL MANY TIMES BE A VERY SMALL GROUP */ /* AT THE END. USE SEPARATE LOOPS FOR MISSING AND NO MISSING */ /* USE SEPARATE LOOPS FOR MISSING AND NO MISSING VALUES */ /* FOR EFFICIENCY. */ if (*is523 == 0) { i__1 = nendb; for (k = mstart; k <= i__1; ++k) { if (ic[k] <= minb) { minb = ic[k]; /* NOTE LE, NOT LT. LT COULD BE USED BUT THEN A */ /* RECOMPUTE OVER THE WHOLE GROUP WOULD BE NEEDED */ /* MORE OFTEN. SAME REASONING FOR GE AND OTHER */ /* LOOPS BELOW. */ minbk = k; } if (ic[k] >= maxb) { maxb = ic[k]; maxbk = k; } /* L155: */ } } else if (*is523 == 1) { i__1 = nendb; for (k = mstart; k <= i__1; ++k) { if (ic[k] == *missp) { goto L157; } if (ic[k] <= minb) { minb = ic[k]; minbk = k; } if (ic[k] >= maxb) { maxb = ic[k]; maxbk = k; } L157: ; } } else { i__1 = nendb; for (k = mstart; k <= i__1; ++k) { if (ic[k] == *missp || ic[k] == *misss) { goto L160; } if (ic[k] <= minb) { minb = ic[k]; minbk = k; } if (ic[k] >= maxb) { maxb = ic[k]; maxbk = k; } L160: ; } } kountb = nendb - ktotal; misllb = 0; if (minb != mallow) { goto L165; } /* ALL MISSING VALUES MUST BE ACCOMMODATED. */ minb = 0; maxb = 0; misllb = 1; ibitb = 0; if (*is523 != 2) { goto L170; } /* WHEN ALL VALUES ARE MISSING AND THERE ARE NO SECONDARY */ /* MISSING VALUES, IBITB = 0. OTHERWISE, IBITB MUST BE */ /* CALCULATED. */ L165: for (ibitb = ibitbs; ibitb <= 30; ++ibitb) { if (maxb - minb < ibxx2[ibitb] - lmiss) { goto L170; } /* L166: */ } /* WRITE(KFILDO,167)MAXB,MINB */ /* 167 FORMAT(' ****ERROR IN PACK_GP. VALUE WILL NOT PACK IN 30 BITS.', */ /* 1 ' MAXB ='I13,' MINB ='I13,'. ERROR AT 167.') */ *ier = 706; goto L900; /* COMPARE THE BITS NEEDED TO PACK GROUP B WITH THOSE NEEDED */ /* TO PACK GROUP A. IF IBITB GE IBITA, TRY TO ADD TO GROUP A. */ /* IF NOT, TRY TO ADD A'S POINTS TO B, UNLESS ADDITION TO A */ /* HAS BEEN DONE. THIS LATTER IS CONTROLLED WITH ADDA. */ L170: /* ***D WRITE(KFILDO,171)KOUNTA,KTOTAL,MINA,MAXA,IBITA,MISLLA, */ /* ***D 1 MINB,MAXB,IBITB,MISLLB */ /* ***D171 FORMAT(' AT 171, KOUNTA ='I8,' KTOTAL ='I8,' MINA ='I8, */ /* ***D 1 ' MAXA ='I8,' IBITA ='I3,' MISLLA ='I3, */ /* ***D 2 ' MINB ='I8,' MAXB ='I8,' IBITB ='I3,' MISLLB ='I3) */ if (ibitb >= ibita) { goto L180; } if (adda) { goto L200; } /* ************************************* */ /* GROUP B REQUIRES LESS BITS THAN GROUP A. PUT AS MANY OF A'S */ /* POINTS INTO B AS POSSIBLE WITHOUT EXCEEDING THE NUMBER OF */ /* BITS NECESSARY TO PACK GROUP B. */ /* ************************************* */ kounts = kounta; /* KOUNTA REFERS TO THE PRESENT GROUP A. */ mintst = minb; maxtst = maxb; mintstk = minbk; maxtstk = maxbk; /* USE SEPARATE LOOPS FOR MISSING AND NO MISSING VALUES */ /* FOR EFFICIENCY. */ if (*is523 == 0) { i__1 = kstart; for (k = ktotal; k >= i__1; --k) { /* START WITH THE END OF THE GROUP AND WORK BACKWARDS. */ if (ic[k] < minb) { mintst = ic[k]; mintstk = k; } else if (ic[k] > maxb) { maxtst = ic[k]; maxtstk = k; } if (maxtst - mintst >= ibxx2[ibitb]) { goto L174; } /* NOTE THAT FOR THIS LOOP, LMISS = 0. */ minb = mintst; maxb = maxtst; minbk = mintstk; maxbk = maxtstk; --kounta; /* THERE IS ONE LESS POINT NOW IN A. */ /* L1715: */ } } else if (*is523 == 1) { i__1 = kstart; for (k = ktotal; k >= i__1; --k) { /* START WITH THE END OF THE GROUP AND WORK BACKWARDS. */ if (ic[k] == *missp) { goto L1718; } if (ic[k] < minb) { mintst = ic[k]; mintstk = k; } else if (ic[k] > maxb) { maxtst = ic[k]; maxtstk = k; } if (maxtst - mintst >= ibxx2[ibitb] - lmiss) { goto L174; } /* FOR THIS LOOP, LMISS = 1. */ minb = mintst; maxb = maxtst; minbk = mintstk; maxbk = maxtstk; misllb = 0; /* WHEN THE POINT IS NON MISSING, MISLLB SET = 0. */ L1718: --kounta; /* THERE IS ONE LESS POINT NOW IN A. */ /* L1719: */ } } else { i__1 = kstart; for (k = ktotal; k >= i__1; --k) { /* START WITH THE END OF THE GROUP AND WORK BACKWARDS. */ if (ic[k] == *missp || ic[k] == *misss) { goto L1729; } if (ic[k] < minb) { mintst = ic[k]; mintstk = k; } else if (ic[k] > maxb) { maxtst = ic[k]; maxtstk = k; } if (maxtst - mintst >= ibxx2[ibitb] - lmiss) { goto L174; } /* FOR THIS LOOP, LMISS = 2. */ minb = mintst; maxb = maxtst; minbk = mintstk; maxbk = maxtstk; misllb = 0; /* WHEN THE POINT IS NON MISSING, MISLLB SET = 0. */ L1729: --kounta; /* THERE IS ONE LESS POINT NOW IN A. */ /* L173: */ } } /* AT THIS POINT, KOUNTA CONTAINS THE NUMBER OF POINTS TO CLOSE */ /* OUT GROUP A WITH. GROUP B NOW STARTS WITH KSTART+KOUNTA AND */ /* ENDS WITH NENDB. MINB AND MAXB HAVE BEEN ADJUSTED AS */ /* NECESSARY TO REFLECT GROUP B (EVEN THOUGH THE NUMBER OF BITS */ /* NEEDED TO PACK GROUP B HAVE NOT INCREASED, THE END POINTS */ /* OF THE RANGE MAY HAVE). */ L174: if (kounta == kounts) { goto L200; } /* ON TRANSFER, GROUP A WAS NOT CHANGED. CLOSE IT OUT. */ /* ONE OR MORE POINTS WERE TAKEN OUT OF A. RANGE AND IBITA */ /* MAY HAVE TO BE RECOMPUTED; IBITA COULD BE LESS THAN */ /* ORIGINALLY COMPUTED. IN FACT, GROUP A CAN NOW CONTAIN */ /* ONLY ONE POINT AND BE PACKED WITH ZERO BITS */ /* (UNLESS MISSS NE 0). */ nouta = kounts - kounta; ktotal -= nouta; kountb += nouta; if (nenda - nouta > minak && nenda - nouta > maxak) { goto L200; } /* WHEN THE ABOVE TEST IS MET, THE MIN AND MAX OF THE */ /* CURRENT GROUP A WERE WITHIN THE OLD GROUP A, SO THE */ /* RANGE AND IBITA DO NOT NEED TO BE RECOMPUTED. */ /* NOTE THAT MINAK AND MAXAK ARE NO LONGER NEEDED. */ ibita = 0; mina = mallow; maxa = -mallow; /* USE SEPARATE LOOPS FOR MISSING AND NO MISSING VALUES */ /* FOR EFFICIENCY. */ if (*is523 == 0) { i__1 = nenda - nouta; for (k = kstart; k <= i__1; ++k) { if (ic[k] < mina) { mina = ic[k]; } if (ic[k] > maxa) { maxa = ic[k]; } /* L1742: */ } } else if (*is523 == 1) { i__1 = nenda - nouta; for (k = kstart; k <= i__1; ++k) { if (ic[k] == *missp) { goto L1744; } if (ic[k] < mina) { mina = ic[k]; } if (ic[k] > maxa) { maxa = ic[k]; } L1744: ; } } else { i__1 = nenda - nouta; for (k = kstart; k <= i__1; ++k) { if (ic[k] == *missp || ic[k] == *misss) { goto L175; } if (ic[k] < mina) { mina = ic[k]; } if (ic[k] > maxa) { maxa = ic[k]; } L175: ; } } mislla = 0; if (mina != mallow) { goto L1750; } /* ALL MISSING VALUES MUST BE ACCOMMODATED. */ mina = 0; maxa = 0; mislla = 1; if (*is523 != 2) { goto L177; } /* WHEN ALL VALUES ARE MISSING AND THERE ARE NO SECONDARY */ /* MISSING VALUES IBITA = 0 AS ORIGINALLY SET. OTHERWISE, */ /* IBITA MUST BE CALCULATED. */ L1750: itest = maxa - mina + lmiss; for (ibita = 0; ibita <= 30; ++ibita) { if (itest < ibxx2[ibita]) { goto L177; } /* *** THIS TEST IS THE SAME AS: */ /* *** IF(MAXA-MINA.LT.IBXX2(IBITA)-LMISS)GO TO 177 */ /* L176: */ } /* WRITE(KFILDO,1760)MAXA,MINA */ /* 1760 FORMAT(' ****ERROR IN PACK_GP. VALUE WILL NOT PACK IN 30 BITS.', */ /* 1 ' MAXA ='I13,' MINA ='I13,'. ERROR AT 1760.') */ *ier = 706; goto L900; L177: goto L200; /* ************************************* */ /* AT THIS POINT, GROUP B REQUIRES AS MANY BITS TO PACK AS GROUPA. */ /* THEREFORE, TRY TO ADD INC POINTS TO GROUP A WITHOUT INCREASING */ /* IBITA. THIS AUGMENTED GROUP IS CALLED GROUP C. */ /* ************************************* */ L180: if (mislla == 1) { minc = mallow; minck = mallow; maxc = -mallow; maxck = -mallow; } else { minc = mina; maxc = maxa; minck = minak; maxck = minak; } nount = 0; if (*nxy - (ktotal + kinc) <= lminpk / 2) { kinc = *nxy - ktotal; } /* ABOVE STATEMENT CONSTRAINS THE LAST GROUP TO BE NOT LESS THAN */ /* LMINPK/2 IN SIZE. IF A PROVISION LIKE THIS IS NOT INCLUDED, */ /* THERE WILL MANY TIMES BE A VERY SMALL GROUP AT THE END. */ /* USE SEPARATE LOOPS FOR MISSING AND NO MISSING VALUES */ /* FOR EFFICIENCY. SINCE KINC IS USUALLY 1, USING SEPARATE */ /* LOOPS HERE DOESN'T BUY MUCH. A MISSING VALUE WILL ALWAYS */ /* TRANSFER BACK TO GROUP A. */ if (*is523 == 0) { /* Computing MIN */ i__2 = ktotal + kinc; /*i__1 = min(i__2,*nxy);*/ i__1 = (i__2 < *nxy) ? i__2 : *nxy; for (k = ktotal + 1; k <= i__1; ++k) { if (ic[k] < minc) { minc = ic[k]; minck = k; } if (ic[k] > maxc) { maxc = ic[k]; maxck = k; } ++nount; /* L185: */ } } else if (*is523 == 1) { /* Computing MIN */ i__2 = ktotal + kinc; /*i__1 = min(i__2,*nxy);*/ i__1 = (i__2 < *nxy) ? i__2 : *nxy; for (k = ktotal + 1; k <= i__1; ++k) { if (ic[k] == *missp) { goto L186; } if (ic[k] < minc) { minc = ic[k]; minck = k; } if (ic[k] > maxc) { maxc = ic[k]; maxck = k; } L186: ++nount; /* L187: */ } } else { /* Computing MIN */ i__2 = ktotal + kinc; /*i__1 = min(i__2,*nxy);*/ i__1 = (i__2 < *nxy) ? i__2 : *nxy; for (k = ktotal + 1; k <= i__1; ++k) { if (ic[k] == *missp || ic[k] == *misss) { goto L189; } if (ic[k] < minc) { minc = ic[k]; minck = k; } if (ic[k] > maxc) { maxc = ic[k]; maxck = k; } L189: ++nount; /* L190: */ } } /* ***D WRITE(KFILDO,191)KOUNTA,KTOTAL,MINA,MAXA,IBITA,MISLLA, */ /* ***D 1 MINC,MAXC,NOUNT,IC(KTOTAL),IC(KTOTAL+1) */ /* ***D191 FORMAT(' AT 191, KOUNTA ='I8,' KTOTAL ='I8,' MINA ='I8, */ /* ***D 1 ' MAXA ='I8,' IBITA ='I3,' MISLLA ='I3, */ /* ***D 2 ' MINC ='I8,' MAXC ='I8, */ /* ***D 3 ' NOUNT ='I5,' IC(KTOTAL) ='I9,' IC(KTOTAL+1) =',I9) */ /* IF THE NUMBER OF BITS NEEDED FOR GROUP C IS GT IBITA, */ /* THEN THIS GROUP A IS A GROUP TO PACK. */ if (minc == mallow) { minc = mina; maxc = maxa; minck = minak; maxck = maxak; misllc = 1; goto L195; /* WHEN THE NEW VALUE(S) ARE MISSING, THEY CAN ALWAYS */ /* BE ADDED. */ } else { misllc = 0; } if (maxc - minc >= ibxx2[ibita] - lmiss) { goto L200; } /* THE BITS NECESSARY FOR GROUP C HAS NOT INCREASED FROM THE */ /* BITS NECESSARY FOR GROUP A. ADD THIS POINT(S) TO GROUP A. */ /* COMPUTE THE NEXT GROUP B, ETC., UNLESS ALL POINTS HAVE BEEN */ /* USED. */ L195: ktotal += nount; kounta += nount; mina = minc; maxa = maxc; minak = minck; maxak = maxck; mislla = misllc; adda = TRUE_; if (ktotal >= *nxy) { goto L200; } if (minbk > ktotal && maxbk > ktotal) { mstart = nendb + 1; /* THE MAX AND MIN OF GROUP B WERE NOT FROM THE POINTS */ /* REMOVED, SO THE WHOLE GROUP DOES NOT HAVE TO BE LOOKED */ /* AT TO DETERMINE THE NEW MAX AND MIN. RATHER START */ /* JUST BEYOND THE OLD NENDB. */ ibitbs = ibitb; nendb = 1; goto L150; } else { goto L140; } /* ************************************* */ /* GROUP A IS TO BE PACKED. STORE VALUES IN JMIN( ), JMAX( ), */ /* LBIT( ), AND NOV( ). */ /* ************************************* */ L200: ++(*lx); if (*lx <= *ndg) { goto L205; } lminpk += lminpk / 2; /* WRITE(KFILDO,201)NDG,LMINPK,LX */ /* 201 FORMAT(' ****NDG ='I5,' NOT LARGE ENOUGH.', */ /* 1 ' LMINPK IS INCREASED TO 'I3,' FOR THIS FIELD.'/ */ /* 2 ' LX = 'I10) */ iersav = 716; goto L105; L205: jmin[*lx] = mina; jmax[*lx] = maxa; lbit[*lx] = ibita; nov[*lx] = kounta; kstart = ktotal + 1; if (mislla == 0) { misslx[*lx - 1] = mallow; } else { misslx[*lx - 1] = ic[ktotal]; /* IC(KTOTAL) WAS THE LAST VALUE PROCESSED. IF MISLLA NE 0, */ /* THIS MUST BE THE MISSING VALUE FOR THIS GROUP. */ } /* ***D WRITE(KFILDO,206)MISLLA,IC(KTOTAL),KTOTAL,LX,JMIN(LX),JMAX(LX), */ /* ***D 1 LBIT(LX),NOV(LX),MISSLX(LX) */ /* ***D206 FORMAT(' AT 206, MISLLA ='I2,' IC(KTOTAL) ='I5,' KTOTAL ='I8, */ /* ***D 1 ' LX ='I6,' JMIN(LX) ='I8,' JMAX(LX) ='I8, */ /* ***D 2 ' LBIT(LX) ='I5,' NOV(LX) ='I8,' MISSLX(LX) =',I7) */ if (ktotal >= *nxy) { goto L209; } /* THE NEW GROUP A WILL BE THE PREVIOUS GROUP B. SET LIMITS, ETC. */ ibita = ibitb; mina = minb; maxa = maxb; minak = minbk; maxak = maxbk; mislla = misllb; nenda = nendb; kounta = kountb; ktotal += kounta; adda = FALSE_; goto L133; /* ************************************* */ /* CALCULATE IBIT, THE NUMBER OF BITS NEEDED TO HOLD THE GROUP */ /* MINIMUM VALUES. */ /* ************************************* */ L209: *ibit = 0; i__1 = *lx; for (l = 1; l <= i__1; ++l) { L210: if (jmin[l] < ibxx2[*ibit]) { goto L220; } ++(*ibit); goto L210; L220: ; } /* INSERT THE VALUE IN JMIN( ) TO BE USED FOR ALL MISSING */ /* VALUES WHEN LBIT( ) = 0. WHEN SECONDARY MISSING */ /* VALUES CAN BE PRESENT, LBIT(L) WILL NOT = 0. */ if (*is523 == 1) { i__1 = *lx; for (l = 1; l <= i__1; ++l) { if (lbit[l] == 0) { if (misslx[l - 1] == *missp) { jmin[l] = ibxx2[*ibit] - 1; } } /* L226: */ } } /* ************************************* */ /* CALCULATE JBIT, THE NUMBER OF BITS NEEDED TO HOLD THE BITS */ /* NEEDED TO PACK THE VALUES IN THE GROUPS. BUT FIND AND */ /* REMOVE THE REFERENCE VALUE FIRST. */ /* ************************************* */ /* WRITE(KFILDO,228)CFEED,LX */ /* 228 FORMAT(A1,/' *****************************************' */ /* 1 /' THE GROUP WIDTHS LBIT( ) FOR ',I8,' GROUPS' */ /* 2 /' *****************************************') */ /* WRITE(KFILDO,229) (LBIT(J),J=1,MIN(LX,100)) */ /* 229 FORMAT(/' '20I6) */ *lbitref = lbit[1]; i__1 = *lx; for (k = 1; k <= i__1; ++k) { if (lbit[k] < *lbitref) { *lbitref = lbit[k]; } /* L230: */ } if (*lbitref != 0) { i__1 = *lx; for (k = 1; k <= i__1; ++k) { lbit[k] -= *lbitref; /* L240: */ } } /* WRITE(KFILDO,241)CFEED,LBITREF */ /* 241 FORMAT(A1,/' *****************************************' */ /* 1 /' THE GROUP WIDTHS LBIT( ) AFTER REMOVING REFERENCE ', */ /* 2 I8, */ /* 3 /' *****************************************') */ /* WRITE(KFILDO,242) (LBIT(J),J=1,MIN(LX,100)) */ /* 242 FORMAT(/' '20I6) */ *jbit = 0; i__1 = *lx; for (k = 1; k <= i__1; ++k) { L310: if (lbit[k] < ibxx2[*jbit]) { goto L320; } ++(*jbit); goto L310; L320: ; } /* ************************************* */ /* CALCULATE KBIT, THE NUMBER OF BITS NEEDED TO HOLD THE NUMBER */ /* OF VALUES IN THE GROUPS. BUT FIND AND REMOVE THE */ /* REFERENCE FIRST. */ /* ************************************* */ /* WRITE(KFILDO,321)CFEED,LX */ /* 321 FORMAT(A1,/' *****************************************' */ /* 1 /' THE GROUP SIZES NOV( ) FOR ',I8,' GROUPS' */ /* 2 /' *****************************************') */ /* WRITE(KFILDO,322) (NOV(J),J=1,MIN(LX,100)) */ /* 322 FORMAT(/' '20I6) */ *novref = nov[1]; i__1 = *lx; for (k = 1; k <= i__1; ++k) { if (nov[k] < *novref) { *novref = nov[k]; } /* L400: */ } if (*novref > 0) { i__1 = *lx; for (k = 1; k <= i__1; ++k) { nov[k] -= *novref; /* L405: */ } } /* WRITE(KFILDO,406)CFEED,NOVREF */ /* 406 FORMAT(A1,/' *****************************************' */ /* 1 /' THE GROUP SIZES NOV( ) AFTER REMOVING REFERENCE ',I8, */ /* 2 /' *****************************************') */ /* WRITE(KFILDO,407) (NOV(J),J=1,MIN(LX,100)) */ /* 407 FORMAT(/' '20I6) */ /* WRITE(KFILDO,408)CFEED */ /* 408 FORMAT(A1,/' *****************************************' */ /* 1 /' THE GROUP REFERENCES JMIN( )' */ /* 2 /' *****************************************') */ /* WRITE(KFILDO,409) (JMIN(J),J=1,MIN(LX,100)) */ /* 409 FORMAT(/' '20I6) */ *kbit = 0; i__1 = *lx; for (k = 1; k <= i__1; ++k) { L410: if (nov[k] < ibxx2[*kbit]) { goto L420; } ++(*kbit); goto L410; L420: ; } /* DETERMINE WHETHER THE GROUP SIZES SHOULD BE REDUCED */ /* FOR SPACE EFFICIENCY. */ if (ired == 0) { reduce(kfildo, &jmin[1], &jmax[1], &lbit[1], &nov[1], lx, ndg, ibit, jbit, kbit, novref, ibxx2, ier); if (*ier == 714 || *ier == 715) { /* REDUCE HAS ABORTED. REEXECUTE PACK_GP WITHOUT REDUCE. */ /* PROVIDE FOR A NON FATAL RETURN FROM REDUCE. */ iersav = *ier; ired = 1; *ier = 0; goto L102; } } if ( misslx != 0 ) { free(misslx); misslx=0; } /* CALL TIMPR(KFILDO,KFILDO,'END PACK_GP ') */ if (iersav != 0) { *ier = iersav; return 0; } /* 900 IF(IER.NE.0)RETURN1 */ L900: if ( misslx != 0 ) free(misslx); return 0; } /* pack_gp__ */ g2clib-1.6.0/pdstemplates.c0000755002373300042670000004026112650420041015374 0ustar Boi.Vuongglobal#include <stdlib.h> #include "grib2.h" #include "pdstemplates.h" g2int getpdsindex(g2int number) ///$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: getpdsindex // PRGMMR: Gilbert ORG: W/NP11 DATE: 2001-06-28 // // ABSTRACT: This function returns the index of specified Product // Definition Template 4.NN (NN=number) in array templates. // // PROGRAM HISTORY LOG: // 2001-06-28 Gilbert // 2009-01-14 Vuong Changed structure name template to gtemplate // 2009-12-15 Vuong Added Product Definition Template 4.31 // Added Product Definition Template 4.15 // 2010-08-03 Vuong Added Product Definition Template 4.42 and 4.43 // 2010-12-08 Vuong Corrected Product Definition Template 4.42 and 4.43 // 2012-03-29 Vuong Added Templates 4.44,4.45,4.46,4.47,4.48,4.50, // 4.51,4.91,4.32 and 4.52 // 2013-08-05 Vuong Corrected 4.91 and added Templates 4.33,4.34,4.53,4.54 // 2015-10-07 Vuong Added Templates 4.57, 4.60, 4.61 and // allow a forecast time to be negative // USAGE: index=getpdsindex(number) // INPUT ARGUMENT LIST: // number - NN, indicating the number of the Product Definition // Template 4.NN that is being requested. // // RETURNS: Index of PDT 4.NN in array templates, if template exists. // = -1, otherwise. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$/ { g2int j,getpdsindex=-1; for (j=0;j<MAXPDSTEMP;j++) { if (number == templatespds[j].template_num) { getpdsindex=j; return(getpdsindex); } } return(getpdsindex); } gtemplate *getpdstemplate(g2int number) ///$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: getpdstemplate // PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-05-11 // // ABSTRACT: This subroutine returns PDS template information for a // specified Product Definition Template 4.NN. // The number of entries in the template is returned along with a map // of the number of octets occupied by each entry. Also, a flag is // returned to indicate whether the template would need to be extended. // // PROGRAM HISTORY LOG: // 2000-05-11 Gilbert // 2009-01-14 Vuong Changed structure name template to gtemplate // 2009-08-05 Vuong Added Product Definition Template 4.31 // 2010-08-03 Vuong Added Product Definition Template 4.42 and 4.43 // 2010-12-08 Vuong Corrected Product Definition Template 4.42 and 4.43 // 2012-02-15 Vuong Added Templates 4.44,4.45,4.46,4.47,4.48,4.50, // 4.51,4.91,4.32 and 4.52 // 2013-08-05 Vuong Corrected 4.91 and added Templates 4.33,4.34,4.53,4.54 // 2015-10-07 Vuong Added Templates 4.57, 4.60, 4.61 and // allow a forecast time to be negative // // USAGE: CALL getpdstemplate(number) // INPUT ARGUMENT LIST: // number - NN, indicating the number of the Product Definition // Template 4.NN that is being requested. // // RETURN VALUE: // - Pointer to the returned template struct. // Returns NULL pointer, if template not found. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$/ { g2int index; gtemplate *new; index=getpdsindex(number); if (index != -1) { new=(gtemplate *)malloc(sizeof(gtemplate)); new->type=4; new->num=templatespds[index].template_num; new->maplen=templatespds[index].mappdslen; new->needext=templatespds[index].needext; new->map=(g2int *)templatespds[index].mappds; new->extlen=0; new->ext=0; //NULL return(new); } else { printf("getpdstemplate: PDS Template 4.%d not defined.\n",(int)number); return(0); //NULL } return(0); //NULL } gtemplate *extpdstemplate(g2int number,g2int *list) ///$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: extpdstemplate // PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-05-11 // // ABSTRACT: This subroutine generates the remaining octet map for a // given Product Definition Template, if required. Some Templates can // vary depending on data values given in an earlier part of the // Template, and it is necessary to know some of the earlier entry // values to generate the full octet map of the Template. // // PROGRAM HISTORY LOG: // 2000-05-11 Gilbert // 2009-01-14 Vuong Changed structure name template to gtemplate // 2009-08-05 Vuong Added Product Definition Template 4.31 // 2010-08-03 Vuong Added Product Definition Template 4.42 and 4.43 // 2010-12-08 Vuong Corrected Product Definition Template 4.42 and 4.43 // 2012-02-15 Vuong Added Templates 4.44,4.45,4.46,4.47,4.48,4.50, // 4.51,4.91,4.32 and 4.52 // 2013-08-05 Vuong Corrected 4.91 and added Templates 4.33,4.34,4.53,4.54 // 2015-10-07 Vuong Added Templates 4.57, 4.60, 4.61 and // allow a forecast time to be negative // // USAGE: CALL extpdstemplate(number,list) // INPUT ARGUMENT LIST: // number - NN, indicating the number of the Product Definition // Template 4.NN that is being requested. // list() - The list of values for each entry in the // the Product Definition Template 4.NN. // // RETURN VALUE: // - Pointer to the returned template struct. // Returns NULL pointer, if template not found. // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { gtemplate *new; g2int index,i,j,k,l; index=getpdsindex(number); if (index == -1) return(0); new=getpdstemplate(number); if ( ! new->needext ) return(new); if ( number == 3 ) { new->extlen=list[26]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { new->ext[i]=1; } } else if ( number == 4 ) { new->extlen=list[25]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { new->ext[i]=1; } } else if ( number == 8 ) { if ( list[21] > 1 ) { new->extlen=(list[21]-1)*6; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (j=2;j<=list[21];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[23+k]; } } } } else if ( number == 9 ) { if ( list[28] > 1 ) { new->extlen=(list[28]-1)*6; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (j=2;j<=list[28];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[30+k]; } } } } else if ( number == 10 ) { if ( list[22] > 1 ) { new->extlen=(list[22]-1)*6; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (j=2;j<=list[22];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[24+k]; } } } } else if ( number == 11 ) { if ( list[24] > 1 ) { new->extlen=(list[24]-1)*6; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (j=2;j<=list[24];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[26+k]; } } } } else if ( number == 12 ) { if ( list[23] > 1 ) { new->extlen=(list[23]-1)*6; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (j=2;j<=list[23];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[25+k]; } } } } else if ( number == 13 ) { new->extlen=((list[37]-1)*6)+list[26]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); if ( list[37] > 1 ) { for (j=2;j<=list[37];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[39+k]; } } } l=(list[37]-1)*6; if ( l<0 ) l=0; for (i=0;i<list[26];i++) { new->ext[l+i]=1; } } else if ( number == 14 ) { new->extlen=((list[36]-1)*6)+list[25]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); if ( list[36] > 1 ) { for (j=2;j<=list[36];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[38+k]; } } } l=(list[36]-1)*6; if ( l<0 ) l=0; for (i=0;i<list[25];i++) { new->ext[l+i]=1; } } else if ( number == 30 ) { new->extlen=list[4]*5; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<list[4];i++) { l=i*5; new->ext[l]=2; new->ext[l+1]=2; new->ext[l+2]=1; new->ext[l+3]=1; new->ext[l+4]=4; } } else if ( number == 31 ) { new->extlen=list[4]*5; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<list[4];i++) { l=i*5; new->ext[l]=2; new->ext[l+1]=2; new->ext[l+2]=2; new->ext[l+3]=1; new->ext[l+4]=4; } } else if ( number == 42 ) { if ( list[22] > 1 ) { new->extlen=(list[22]-1)*6; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (j=2;j<=list[22];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[24+k]; } } } } else if ( number == 43 ) { if ( list[25] > 1 ) { new->extlen=(list[25]-1)*6; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (j=2;j<=list[25];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[27+k]; } } } } else if ( number == 32 ) { new->extlen=list[9]*10; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<list[9];i++) { l=i*5; new->ext[l]=2; new->ext[l+1]=2; new->ext[l+2]=2; new->ext[l+3]=-1; new->ext[l+4]=-4; } } else if ( number == 46 ) { if ( list[27] > 1 ) { new->extlen=(list[27]-1)*6; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (j=2;j<=list[27];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[29+k]; } } } } else if ( number == 47 ) { if ( list[30] > 1 ) { new->extlen=(list[30]-1)*6; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (j=2;j<=list[30];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[32+k]; } } } else if ( number == 51 ) { new->extlen=list[15]*11; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<list[15];i++) { l=i*6; new->ext[l]=1; new->ext[l+1]=1; new->ext[l+2]=-1; new->ext[l+3]=-4; new->ext[l+4]=-1; new->ext[l+5]=-4; } } else if ( number == 33 ) { new->extlen=list[9]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { new->ext[i]=1; } } else if ( number == 34 ) { new->extlen=((list[24]-1)*6)+list[9]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); if ( list[24] > 1 ) { for (j=2;j<=list[24];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[26+k]; } } } l=(list[24]-1)*6; if ( l<0 ) l=0; for (i=0;i<list[9];i++) { new->ext[l+i]=1; } } else if ( number == 53 ) { new->extlen=list[3]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { new->ext[i]=1; } } else if ( number == 54 ) { new->extlen=list[3]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<new->extlen;i++) { new->ext[i]=1; } } else if ( number == 91 ) { new->extlen=((list[28]-1)*6)+list[15]; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); if ( list[28] > 1 ) { for (j=2;j<=list[28];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[30+k]; } } } l=(list[29]-1)*6; if ( l<0 ) l=0; for (i=0;i<list[15];i++) { new->ext[l+i]=1; } } // PDT 4.57 (10/07/2015) else if ( number == 57 ) { new->extlen=list[6]*15; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (i=0;i<list[6];i++) { l=i*15; new->ext[l]=1; new->ext[l+1]=-4; new->ext[l+2]=1; new->ext[l+3]=1; new->ext[l+4]=1; new->ext[l+5]=2; new->ext[l+6]=1; new->ext[l+7]=1; new->ext[l+8]=-4; new->ext[l+9]=1; new->ext[l+10]=-1; new->ext[l+11]=-4; new->ext[l+12]=1; new->ext[l+13]=-1; new->ext[l+14]=-4; } } // PDT 4.61 (10/07/2015) else if ( number == 61 ) { if ( list[30] > 1 ) { new->extlen=(list[30]-1)*6; new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen); for (j=2;j<=list[30];j++) { l=(j-2)*6; for (k=0;k<6;k++) { new->ext[l+k]=new->map[32+k]; } } } } } return(new); } g2clib-1.6.0/pdstemplates.h0000755002373300042670000003172512650424067015422 0ustar Boi.Vuongglobal#ifndef _pdstemplates_H #define _pdstemplates_H #include "grib2.h" // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-26 // // ABSTRACT: This inculde file contains info on all the available // GRIB2 Product Definition Templates used in Section 4 (PDS). // The information decribing each template is stored in the // pdstemplate structure defined below. // // Each Template has three parts: The number of entries in the template // (mappdslen); A map of the template (mappds), which contains the // number of octets in which to pack each of the template values; and // a logical value (needext) that indicates whether the Template needs // to be extended. In some cases the number of entries in a template // can vary depending upon values specified in the "static" part of // the template. ( See Template 4.3 as an example ) // // NOTE: Array mappds contains the number of octets in which the // corresponding template values will be stored. A negative value in // mappds is used to indicate that the corresponding template entry can // contain negative values. This information is used later when packing // (or unpacking) the template data values. Negative data values in GRIB // are stored with the left most bit set to one, and a negative number // of octets value in mappds[] indicates that this possibility should // be considered. The number of octets used to store the data value // in this case would be the absolute value of the negative value in // mappds[]. // // 2005-12-08 Gilbert Allow negative scale factors and limits for // Templates 4.5 and 4.9 // 2009-12-15 Vuong Added Product Definition Template 4.31 // Added Product Definition Template 4.15 // 2010-08-03 Vuong Added Product Definition Template 4.40,4.41,4.42,4.43 // 2010-12-08 Vuong Corrected Definition Template 4.42,4.43 // 2010-12-08 Vuong Corrected Definition Template 4.42,4.43 // 2012-03-29 Vuong Added Templates 4.44,4.45,4.46,4.47,4.48,4.50, // 4.51,4.91,4.32 and 4.52 // 2013-08-05 Vuong Corrected 4.91 and added Templates 4.33,4.34,4.53,4.54 // 2015-10-07 Vuong Added Templates 4.57, 4.60, 4.61 and // allow a forecast time to be negative // //$$$ #define MAXPDSTEMP 47 // maximum number of templates #define MAXPDSMAPLEN 200 // maximum template map length struct pdstemplate { g2int template_num; g2int mappdslen; g2int needext; g2int mappds[MAXPDSMAPLEN]; }; const struct pdstemplate templatespds[MAXPDSTEMP] = { // 4.0: Analysis or Forecast at Horizontal Level/Layer // at a point in time {0,15,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, // 4.1: Individual Ensemble Forecast at Horizontal Level/Layer // at a point in time {1,18,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, // 4.2: Derived Fcst based on whole Ensemble at Horiz Level/Layer // at a point in time {2,17,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1} }, // 4.3: Derived Fcst based on Ensemble cluster over rectangular // area at Horiz Level/Layer at a point in time {3,31,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,-4,4,4,1,-1,4,-1,4} }, // 4.4: Derived Fcst based on Ensemble cluster over circular // area at Horiz Level/Layer at a point in time {4,30,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,4,4,1,-1,4,-1,4} }, // 4.5: Probablility Forecast at Horiz Level/Layer // at a point in time {5,22,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,-1,-4,-1,-4} }, // 4.6: Percentile Forecast at Horiz Level/Layer // at a point in time {6,16,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1} }, // 4.7: Analysis or Forecast Error at Horizontal Level/Layer // at a point in time {7,15,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, // 4.8: Ave/Accum/etc... at Horiz Level/Layer // in a time interval {8,29,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // 4.9: Probablility Forecast at Horiz Level/Layer // in a time interval {9,36,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,-1,-4,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // 4.10: Percentile Forecast at Horiz Level/Layer // in a time interval {10,30,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // 4.11: Individual Ensemble Forecast at Horizontal Level/Layer // in a time interval {11,32,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // 4.12: Derived Fcst based on whole Ensemble at Horiz Level/Layer // in a time interval {12,31,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // 4.13: Derived Fcst based on Ensemble cluster over rectangular // area at Horiz Level/Layer in a time interval {13,45,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,-4,4,4,1,-1,4,-1,4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // 4.14: Derived Fcst based on Ensemble cluster over circular // area at Horiz Level/Layer in a time interval {14,44,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,4,4,1,-1,4,-1,4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // 4.15: Average, accumulation, extreme values or other statistically-processed values over a // spatial area at a horizontal level or in a horizontal layer at a point in time {15,18,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, // 4.20: Radar Product {20,19,0, {1,1,1,1,1,-4,4,2,4,2,1,1,1,1,1,2,1,3,2} }, // 4.30: Satellite Product {30,5,1, {1,1,1,1,1} }, // 4.31: Satellite Product {31,5,1, {1,1,1,1,1} }, // 4.40: Analysis or forecast at a horizontal level or in a horizontal layer // at a point in time for atmospheric chemical constituents {40,16,0, {1,1,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, // 4.41: Individual ensemble forecast, control and perturbed, at a horizontal level or // in a horizontal layer at a point in time for atmospheric chemical constituents {41,19,0, {1,1,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, // 4.42: Average, accumulation, and/or extreme values or other statistically-processed values // at a horizontal level or in a horizontal layer in a continuous or non-continuous // time interval for atmospheric chemical constituents {42,30,1, {1,1,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // 4.43: Individual ensemble forecast, control and perturbed, at a horizontal level // or in a horizontal layer in a continuous or non-continuous // time interval for atmospheric chemical constituents {43,33,1, {1,1,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // 4.254: CCITT IA5 Character String {254,3,0, {1,1,4} }, // 4.1000: Cross section of analysis or forecast // at a point in time {1000,9,0, {1,1,1,1,1,2,1,1,-4} }, // 4.1001: Cross section of Ave/Accum/etc... analysis or forecast // in a time interval {1001,16,0, {1,1,1,1,1,2,1,1,4,4,1,1,1,4,1,4} }, // 4.1001: Cross section of Ave/Accum/etc... analysis or forecast // over latitude or longitude {1002,15,0, {1,1,1,1,1,2,1,1,-4,1,1,1,4,4,2} }, // 4.1100: Hovmoller-type grid w/ no averaging or other // statistical processing {1100,15,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, // 4.1100: Hovmoller-type grid with averaging or other // statistical processing {1101,22,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,4,1,1,1,4,1,4} }, // 4.32:Simulate (synthetic) Satellite Product {32,10,1, {1,1,1,1,1,2,1,1,-2,1} }, // 4.44: Analysis or forecast at a horizontal level or in a horizontal layer // at a point in time for Aerosol {44,21,0, {1,1,2,1,-1,-4,-1,-4,1,1,1,2,1,1,-2,1,-1,-4,1,-1,-4} }, // 4.45: Individual ensemble forecast, control and // perturbed, at a horizontal level or in a horizontal layer // at a point in time for Aerosol {45,24,0, {1,1,2,1,-1,-4,-1,-4,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, // 4.46: Ave or Accum or Extreme value at level/layer // at horizontal level or in a horizontal in a continuous or // non-continuous time interval for Aerosol {46,35,1, {1,1,2,1,-1,-4,-1,-4,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // 4.47: Individual ensemble forecast, control and // perturbed, at horizontal level or in a horizontal // in a continuous or non-continuous time interval for Aerosol {47,38,1, {1,1,1,2,1,-1,-4,-1,-4,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // PDT 4.48 // 4.48: Analysis or forecast at a horizontal level or in a horizontal layer // at a point in time for Optical Properties of Aerosol {48,26,0, {1,1,2,1,-1,-4,-1,-4,1,-1,-4,-1,-4,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, // VALIDATION --- PDT 4.50 // 4.50: Analysis or forecast of multi component parameter or // matrix element at a point in time {50,21,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,4,4,4,4} }, // VALIDATION --- PDT 4.52 // 4.52: Analysis or forecast of Wave parameters // at the Sea surface at a point in time {52,15,0, {1,1,1,1,1,1,1,1,2,1,1,-4,1,-1,-4} }, // 4.51: Categorical forecasts at a horizontal level or // in a horizontal layer at a point in time {51,16,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1} }, // 4.91: Categorical forecasts at a horizontal level or // in a horizontal layer at a point in time // in a continuous or non-continuous time interval {91,36,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,-1,-4,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // PDT 4.33 (07/29/2013) // 4.33: Individual ensemble forecast, control, perturbed, // at a horizontal level or in a horizontal layer // at a point in time for simulated (synthetic) Satellite data {33,18,1, {1,1,1,1,1,2,1,1,-4,1,2,2,2,-1,-4,1,1,1} }, // PDT 4.34 (07/29/2013) // 4.34: Individual ensemble forecast, control, perturbed, // at a horizontal level or in a horizontal layer,in a continuous or // non-continuous interval for simulated (synthetic) Satellite data {34,32,1, {1,1,1,1,1,2,1,1,-4,1,2,2,2,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // PDT 4.53 (07/29/2013) // 4.53: Partitioned parameters at // horizontal level or horizontal layer // at a point in time {53,19,1, {1,1,1,1,4,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, // PDT 4.54 (07/29/2013) // 4.54: Individual ensemble forecast, control, perturbed, // at a horizontal level or in a horizontal layer // at a point in time for partitioned parameters {54,22,1, {1,1,1,1,4,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, // PDT 4.57 (10/07/2015) // 4.57: Analysis or Forecast at a horizontal or in a // horizontal layer at a point in time for // atmospheric chemical constituents based on // a distribution function {57,7,1, {1,1,2,2,2,2,1} }, // PDT 4.60 (10/07/2015) // 4.60: Individual ensemble reforecast, control and perturbed, // at a horizontal level or in a horizontal layer // at a point in time {60,24,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1} }, // PDT 4.61 (10/07/2015) // 4.61: Individual ensemble reforecast, control and perturbed, // at a horizontal level or in a horizontal layer // in a continuous or non-continuous time interval {61,38,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, // VALIDATION --- PDT 4.35 // PDT 4.35 (10/07/2015) // 4.35: Individual ensemble reforecast, control and perturbed, // at a horizontal level or in a horizontal layer // in a continuous or non-continuous time interval {35,6,1, {1,1,1,1,1,1} } } ; #endif /* _pdstemplates_H */ g2clib-1.6.0/pngpack.c0000755002373300042670000001255412522400361014317 0ustar Boi.Vuongglobal#include <stdlib.h> #include <math.h> #include "grib2.h" int enc_png(char *,g2int ,g2int ,g2int ,char *); void pngpack(g2float *fld,g2int width,g2int height,g2int *idrstmpl, unsigned char *cpack,g2int *lcpack) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: pngpack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2003-08-27 // // ABSTRACT: This subroutine packs up a data field into PNG image format. // After the data field is scaled, and the reference value is subtracted out, // it is treated as a grayscale image and passed to a PNG encoder. // It also fills in GRIB2 Data Representation Template 5.41 or 5.40010 with // the appropriate values. // // PROGRAM HISTORY LOG: // 2003-08-27 Gilbert // // USAGE: pngpack(g2float *fld,g2int width,g2int height,g2int *idrstmpl, // unsigned char *cpack,g2int *lcpack); // INPUT ARGUMENT LIST: // fld[] - Contains the data values to pack // width - number of points in the x direction // height - number of points in the y direction // idrstmpl - Contains the array of values for Data Representation // Template 5.41 or 5.40010 // [0] = Reference value - ignored on input // [1] = Binary Scale Factor // [2] = Decimal Scale Factor // [3] = number of bits for each data value - ignored on input // [4] = Original field type - currently ignored on input // Data values assumed to be reals. // // OUTPUT ARGUMENT LIST: // idrstmpl - Contains the array of values for Data Representation // Template 5.41 or 5.40010 // [0] = Reference value - set by pngpack routine. // [1] = Binary Scale Factor - unchanged from input // [2] = Decimal Scale Factor - unchanged from input // [3] = Number of bits containing each grayscale pixel value // [4] = Original field type - currently set = 0 on output. // Data values assumed to be reals. // cpack - The packed data field // lcpack - length of packed field cpack. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { g2int *ifld; static g2float alog2=0.69314718; // ln(2.0) g2int j,nbits,imin,imax,maxdif; g2int ndpts,nbytes; g2float bscale,dscale,rmax,rmin,temp; unsigned char *ctemp; ifld=0; ndpts=width*height; bscale=int_power(2.0,-idrstmpl[1]); dscale=int_power(10.0,idrstmpl[2]); // // Find max and min values in the data // rmax=fld[0]; rmin=fld[0]; for (j=1;j<ndpts;j++) { if (fld[j] > rmax) rmax=fld[j]; if (fld[j] < rmin) rmin=fld[j]; } maxdif = (g2int)rint( (rmax-rmin)*dscale*bscale ); // // If max and min values are not equal, pack up field. // If they are equal, we have a constant field, and the reference // value (rmin) is the value for each point in the field and // set nbits to 0. // if (rmin != rmax && maxdif != 0 ) { ifld=(g2int *)malloc(ndpts*sizeof(g2int)); // // Determine which algorithm to use based on user-supplied // binary scale factor and number of bits. // if (idrstmpl[1] == 0) { // // No binary scaling and calculate minumum number of // bits in which the data will fit. // imin=(g2int)rint(rmin*dscale); imax=(g2int)rint(rmax*dscale); maxdif=imax-imin; temp=log((double)(maxdif+1))/alog2; nbits=(g2int)ceil(temp); rmin=(g2float)imin; // scale data for(j=0;j<ndpts;j++) ifld[j]=(g2int)rint(fld[j]*dscale)-imin; } else { // // Use binary scaling factor and calculate minumum number of // bits in which the data will fit. // rmin=rmin*dscale; rmax=rmax*dscale; maxdif=(g2int)rint((rmax-rmin)*bscale); temp=log((double)(maxdif+1))/alog2; nbits=(g2int)ceil(temp); // scale data for (j=0;j<ndpts;j++) ifld[j]=(g2int)rint(((fld[j]*dscale)-rmin)*bscale); } // // Pack data into full octets, then do PNG encode. // and calculate the length of the packed data in bytes // if (nbits <= 8) { nbits=8; } else if (nbits <= 16) { nbits=16; } else if (nbits <= 24) { nbits=24; } else { nbits=32; } nbytes=(nbits/8)*ndpts; ctemp=calloc(nbytes,1); sbits(ctemp,ifld,0,nbits,0,ndpts); // // Encode data into PNG Format. // *lcpack=(g2int)enc_png((char *)ctemp,width,height,nbits,(char *)cpack); if (*lcpack <= 0) { printf("pngpack: ERROR Packing PNG = %d\n",(int)*lcpack); } free(ctemp); } else { nbits=0; *lcpack=0; } // // Fill in ref value and number of bits in Template 5.0 // mkieee(&rmin,idrstmpl+0,1); // ensure reference value is IEEE format idrstmpl[3]=nbits; idrstmpl[4]=0; // original data were reals if (ifld != 0) free(ifld); } g2clib-1.6.0/pngunpack.c0000755002373300042670000000434112522400361014655 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" int dec_png(unsigned char *,g2int *,g2int *,char *); g2int pngunpack(unsigned char *cpack,g2int len,g2int *idrstmpl,g2int ndpts, g2float *fld) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: pngunpack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2003-08-27 // // ABSTRACT: This subroutine unpacks a data field that was packed into a // PNG image format // using info from the GRIB2 Data Representation Template 5.41 or 5.40010. // // PROGRAM HISTORY LOG: // 2003-08-27 Gilbert // // USAGE: pngunpack(unsigned char *cpack,g2int len,g2int *idrstmpl,g2int ndpts, // g2float *fld) // INPUT ARGUMENT LIST: // cpack - The packed data field (character*1 array) // len - length of packed field cpack(). // idrstmpl - Pointer to array of values for Data Representation // Template 5.41 or 5.40010 // ndpts - The number of data values to unpack // // OUTPUT ARGUMENT LIST: // fld[] - Contains the unpacked data values // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { g2int *ifld; g2int j,nbits,iret,width,height; g2float ref,bscale,dscale; unsigned char *ctemp; rdieee(idrstmpl+0,&ref,1); bscale = int_power(2.0,idrstmpl[1]); dscale = int_power(10.0,-idrstmpl[2]); nbits = idrstmpl[3]; // // if nbits equals 0, we have a constant field where the reference value // is the data value at each gridpoint // if (nbits != 0) { ifld=(g2int *)calloc(ndpts,sizeof(g2int)); ctemp=(unsigned char *)calloc(ndpts*4,1); if ( ifld == 0 || ctemp == 0) { fprintf(stderr,"Could not allocate space in jpcunpack.\n Data field NOT upacked.\n"); return(1); } iret=(g2int)dec_png(cpack,&width,&height,ctemp); gbits(ctemp,ifld,0,nbits,0,ndpts); for (j=0;j<ndpts;j++) { fld[j]=(((g2float)ifld[j]*bscale)+ref)*dscale; } free(ctemp); free(ifld); } else { for (j=0;j<ndpts;j++) fld[j]=ref; } return(0); } g2clib-1.6.0/rdieee.c0000755002373300042670000000415212522400361014124 0ustar Boi.Vuongglobal#include "grib2.h" void rdieee(g2int *rieee,g2float *a,g2int num) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: rdieee // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-25 // // ABSTRACT: This subroutine reads a list of real values in // 32-bit IEEE floating point format. // // PROGRAM HISTORY LOG: // 2002-10-25 Gilbert // // USAGE: void rdieee(g2int *rieee,g2float *a,g2int num) // INPUT ARGUMENT LIST: // rieee - g2int array of floating point values in 32-bit IEEE format. // num - Number of floating point values to convert. // // OUTPUT ARGUMENT LIST: // a - float array of real values. a must be allocated with at // least 4*num bytes of memory before calling this function. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { g2int j; g2int isign,iexp,imant; g2float sign,temp; static g2float two23,two126; static g2int test=0; g2intu msk1=0x80000000; // 10000000000000000000000000000000 binary g2int msk2=0x7F800000; // 01111111100000000000000000000000 binary g2int msk3=0x007FFFFF; // 00000000011111111111111111111111 binary if ( test == 0 ) { two23=(g2float)int_power(2.0,-23); two126=(g2float)int_power(2.0,-126); test=1; } for (j=0;j<num;j++) { // // Extract sign bit, exponent, and mantissa // isign=(rieee[j]&msk1)>>31; iexp=(rieee[j]&msk2)>>23; imant=(rieee[j]&msk3); //printf("SAGieee= %ld %ld %ld\n",isign,iexp,imant); sign=1.0; if (isign == 1) sign=-1.0; if ( (iexp > 0) && (iexp < 255) ) { temp=(g2float)int_power(2.0,(iexp-127)); a[j]=sign*temp*(1.0+(two23*(g2float)imant)); } else if ( iexp == 0 ) { if ( imant != 0 ) a[j]=sign*two126*two23*(g2float)imant; else a[j]=sign*0.0; } else if ( iexp == 255 ) a[j]=sign*(1E+37); } } g2clib-1.6.0/reduce.c0000644002373300042670000003636012522400361014141 0ustar Boi.Vuongglobal/* reduce.f -- translated by f2c (version 20031025). You must link the resulting object file with libf2c: on Microsoft Windows system, link with libf2c.lib; on Linux or Unix systems, link with .../path/to/libf2c.a -lm or, if you install libf2c.a in a standard place, with -lf2c -lm -- in that order, at the end of the command line, as in cc *.o -lf2c -lm Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., http://www.netlib.org/f2c/libf2c.zip */ /*#include "f2c.h"*/ #include <stdlib.h> #include "grib2.h" typedef g2int integer; typedef g2float real; /* Subroutine */ int reduce(integer *kfildo, integer *jmin, integer *jmax, integer *lbit, integer *nov, integer *lx, integer *ndg, integer *ibit, integer *jbit, integer *kbit, integer *novref, integer *ibxx2, integer *ier) { /* Initialized data */ static integer ifeed = 12; /* System generated locals */ integer i__1, i__2; /* Local variables */ static integer newboxtp, j, l, m, jj, lxn, left; static real pimp; static integer move, novl; static char cfeed[1]; static integer nboxj[31], lxnkp, iorigb, ibxx2m1, movmin, ntotbt[31], ntotpr, newboxt; integer *newbox, *newboxp; /* NOVEMBER 2001 GLAHN TDL GRIB2 */ /* MARCH 2002 GLAHN COMMENT IER = 715 */ /* MARCH 2002 GLAHN MODIFIED TO ACCOMMODATE LX=1 ON ENTRY */ /* PURPOSE */ /* DETERMINES WHETHER THE NUMBER OF GROUPS SHOULD BE */ /* INCREASED IN ORDER TO REDUCE THE SIZE OF THE LARGE */ /* GROUPS, AND TO MAKE THAT ADJUSTMENT. BY REDUCING THE */ /* SIZE OF THE LARGE GROUPS, LESS BITS MAY BE NECESSARY */ /* FOR PACKING THE GROUP SIZES AND ALL THE INFORMATION */ /* ABOUT THE GROUPS. */ /* THE REFERENCE FOR NOV( ) WAS REMOVED IN THE CALLING */ /* ROUTINE SO THAT KBIT COULD BE DETERMINED. THIS */ /* FURNISHES A STARTING POINT FOR THE ITERATIONS IN REDUCE. */ /* HOWEVER, THE REFERENCE MUST BE CONSIDERED. */ /* DATA SET USE */ /* KFILDO - UNIT NUMBER FOR OUTPUT (PRINT) FILE. (OUTPUT) */ /* VARIABLES IN CALL SEQUENCE */ /* KFILDO = UNIT NUMBER FOR OUTPUT (PRINT) FILE. (INPUT) */ /* JMIN(J) = THE MINIMUM OF EACH GROUP (J=1,LX). IT IS */ /* POSSIBLE AFTER SPLITTING THE GROUPS, JMIN( ) */ /* WILL NOT BE THE MINIMUM OF THE NEW GROUP. */ /* THIS DOESN'T MATTER; JMIN( ) IS REALLY THE */ /* GROUP REFERENCE AND DOESN'T HAVE TO BE THE */ /* SMALLEST VALUE. (INPUT/OUTPUT) */ /* JMAX(J) = THE MAXIMUM OF EACH GROUP (J=1,LX). */ /* (INPUT/OUTPUT) */ /* LBIT(J) = THE NUMBER OF BITS NECESSARY TO PACK EACH GROUP */ /* (J=1,LX). (INPUT/OUTPUT) */ /* NOV(J) = THE NUMBER OF VALUES IN EACH GROUP (J=1,LX). */ /* (INPUT/OUTPUT) */ /* LX = THE NUMBER OF GROUPS. THIS WILL BE INCREASED */ /* IF GROUPS ARE SPLIT. (INPUT/OUTPUT) */ /* NDG = THE DIMENSION OF JMIN( ), JMAX( ), LBIT( ), AND */ /* NOV( ). (INPUT) */ /* IBIT = THE NUMBER OF BITS NECESSARY TO PACK THE JMIN(J) */ /* VALUES, J=1,LX. (INPUT) */ /* JBIT = THE NUMBER OF BITS NECESSARY TO PACK THE LBIT(J) */ /* VALUES, J=1,LX. (INPUT) */ /* KBIT = THE NUMBER OF BITS NECESSARY TO PACK THE NOV(J) */ /* VALUES, J=1,LX. IF THE GROUPS ARE SPLIT, KBIT */ /* IS REDUCED. (INPUT/OUTPUT) */ /* NOVREF = REFERENCE VALUE FOR NOV( ). (INPUT) */ /* IBXX2(J) = 2**J (J=0,30). (INPUT) */ /* IER = ERROR RETURN. (OUTPUT) */ /* 0 = GOOD RETURN. */ /* 714 = PROBLEM IN ALGORITHM. REDUCE ABORTED. */ /* 715 = NGP NOT LARGE ENOUGH. REDUCE ABORTED. */ /* NTOTBT(J) = THE TOTAL BITS USED FOR THE PACKING BITS J */ /* (J=1,30). (INTERNAL) */ /* NBOXJ(J) = NEW BOXES NEEDED FOR THE PACKING BITS J */ /* (J=1,30). (INTERNAL) */ /* NEWBOX(L) = NUMBER OF NEW BOXES (GROUPS) FOR EACH ORIGINAL */ /* GROUP (L=1,LX) FOR THE CURRENT J. (AUTOMATIC) */ /* (INTERNAL) */ /* NEWBOXP(L) = SAME AS NEWBOX( ) BUT FOR THE PREVIOUS J. */ /* THIS ELIMINATES RECOMPUTATION. (AUTOMATIC) */ /* (INTERNAL) */ /* CFEED = CONTAINS THE CHARACTER REPRESENTATION */ /* OF A PRINTER FORM FEED. (CHARACTER) (INTERNAL) */ /* IFEED = CONTAINS THE INTEGER VALUE OF A PRINTER */ /* FORM FEED. (INTERNAL) */ /* IORIGB = THE ORIGINAL NUMBER OF BITS NECESSARY */ /* FOR THE GROUP VALUES. (INTERNAL) */ /* 1 2 3 4 5 6 7 X */ /* NON SYSTEM SUBROUTINES CALLED */ /* NONE */ /* NEWBOX( ) AND NEWBOXP( ) were AUTOMATIC ARRAYS. */ newbox = (integer *)calloc(*ndg,sizeof(integer)); newboxp = (integer *)calloc(*ndg,sizeof(integer)); /* Parameter adjustments */ --nov; --lbit; --jmax; --jmin; /* Function Body */ *ier = 0; if (*lx == 1) { goto L410; } /* IF THERE IS ONLY ONE GROUP, RETURN. */ *(unsigned char *)cfeed = (char) ifeed; /* INITIALIZE NUMBER OF NEW BOXES PER GROUP TO ZERO. */ i__1 = *lx; for (l = 1; l <= i__1; ++l) { newbox[l - 1] = 0; /* L110: */ } /* INITIALIZE NUMBER OF TOTAL NEW BOXES PER J TO ZERO. */ for (j = 1; j <= 31; ++j) { ntotbt[j - 1] = 999999999; nboxj[j - 1] = 0; /* L112: */ } iorigb = (*ibit + *jbit + *kbit) * *lx; /* IBIT = BITS TO PACK THE JMIN( ). */ /* JBIT = BITS TO PACK THE LBIT( ). */ /* KBIT = BITS TO PACK THE NOV( ). */ /* LX = NUMBER OF GROUPS. */ ntotbt[*kbit - 1] = iorigb; /* THIS IS THE VALUE OF TOTAL BITS FOR THE ORIGINAL LX */ /* GROUPS, WHICH REQUIRES KBITS TO PACK THE GROUP */ /* LENGHTS. SETTING THIS HERE MAKES ONE LESS LOOPS */ /* NECESSARY BELOW. */ /* COMPUTE BITS NOW USED FOR THE PARAMETERS DEFINED. */ /* DETERMINE OTHER POSSIBILITES BY INCREASING LX AND DECREASING */ /* NOV( ) WITH VALUES GREATER THAN THRESHOLDS. ASSUME A GROUP IS */ /* SPLIT INTO 2 OR MORE GROUPS SO THAT KBIT IS REDUCED WITHOUT */ /* CHANGING IBIT OR JBIT. */ jj = 0; /* Computing MIN */ i__1 = 30, i__2 = *kbit - 1; /*for (j = min(i__1,i__2); j >= 2; --j) {*/ for (j = (i__1 < i__2) ? i__1 : i__2; j >= 2; --j) { /* VALUES GE KBIT WILL NOT REQUIRE SPLITS. ONCE THE TOTAL */ /* BITS START INCREASING WITH DECREASING J, STOP. ALSO, THE */ /* NUMBER OF BITS REQUIRED IS KNOWN FOR KBITS = NTOTBT(KBIT). */ newboxt = 0; i__1 = *lx; for (l = 1; l <= i__1; ++l) { if (nov[l] < ibxx2[j]) { newbox[l - 1] = 0; /* NO SPLITS OR NEW BOXES. */ goto L190; } else { novl = nov[l]; m = (nov[l] - 1) / (ibxx2[j] - 1) + 1; /* M IS FOUND BY SOLVING THE EQUATION BELOW FOR M: */ /* (NOV(L)+M-1)/M LT IBXX2(J) */ /* M GT (NOV(L)-1)/(IBXX2(J)-1) */ /* SET M = (NOV(L)-1)/(IBXX2(J)-1)+1 */ L130: novl = (nov[l] + m - 1) / m; /* THE +M-1 IS NECESSARY. FOR INSTANCE, 15 WILL FIT */ /* INTO A BOX 4 BITS WIDE, BUT WON'T DIVIDE INTO */ /* TWO BOXES 3 BITS WIDE EACH. */ if (novl < ibxx2[j]) { goto L185; } else { ++m; /* *** WRITE(KFILDO,135)L,NOV(L),NOVL,M,J,IBXX2(J) */ /* *** 135 FORMAT(/' AT 135--L,NOV(L),NOVL,M,J,IBXX2(J)',6I10) */ goto L130; } /* THE ABOVE DO LOOP WILL NEVER COMPLETE. */ } L185: newbox[l - 1] = m - 1; newboxt = newboxt + m - 1; L190: ; } nboxj[j - 1] = newboxt; ntotpr = ntotbt[j]; ntotbt[j - 1] = (*ibit + *jbit) * (*lx + newboxt) + j * (*lx + newboxt); if (ntotbt[j - 1] >= ntotpr) { jj = j + 1; /* THE PLUS IS USED BECAUSE J DECREASES PER ITERATION. */ goto L250; } else { /* SAVE THE TOTAL NEW BOXES AND NEWBOX( ) IN CASE THIS */ /* IS THE J TO USE. */ newboxtp = newboxt; i__1 = *lx; for (l = 1; l <= i__1; ++l) { newboxp[l - 1] = newbox[l - 1]; /* L195: */ } /* WRITE(KFILDO,197)NEWBOXT,IBXX2(J) */ /* 197 FORMAT(/' *****************************************' */ /* 1 /' THE NUMBER OF NEWBOXES PER GROUP OF THE TOTAL', */ /* 2 I10,' FOR GROUP MAXSIZE PLUS 1 ='I10 */ /* 3 /' *****************************************') */ /* WRITE(KFILDO,198) (NEWBOX(L),L=1,LX) */ /* 198 FORMAT(/' '20I6/(' '20I6)) */ } /* 205 WRITE(KFILDO,209)KBIT,IORIGB */ /* 209 FORMAT(/' ORIGINAL BITS WITH KBIT OF',I5,' =',I10) */ /* WRITE(KFILDO,210)(N,N=2,10),(IBXX2(N),N=2,10), */ /* 1 (NTOTBT(N),N=2,10),(NBOXJ(N),N=2,10), */ /* 2 (N,N=11,20),(IBXX2(N),N=11,20), */ /* 3 (NTOTBT(N),N=11,20),(NBOXJ(N),N=11,20), */ /* 4 (N,N=21,30),(IBXX2(N),N=11,20), */ /* 5 (NTOTBT(N),N=21,30),(NBOXJ(N),N=21,30) */ /* 210 FORMAT(/' THE TOTAL BYTES FOR MAXIMUM GROUP LENGTHS BY ROW'// */ /* 1 ' J = THE NUMBER OF BITS PER GROUP LENGTH'/ */ /* 2 ' IBXX2(J) = THE MAXIMUM GROUP LENGTH PLUS 1 FOR THIS J'/ */ /* 3 ' NTOTBT(J) = THE TOTAL BITS FOR THIS J'/ */ /* 4 ' NBOXJ(J) = THE NEW GROUPS FOR THIS J'/ */ /* 5 4(/10X,9I10)/4(/10I10)/4(/10I10)) */ /* L200: */ } L250: pimp = (iorigb - ntotbt[jj - 1]) / (real) iorigb * 100.f; /* WRITE(KFILDO,252)PIMP,KBIT,JJ */ /* 252 FORMAT(/' PERCENT IMPROVEMENT =',F6.1, */ /* 1 ' BY DECREASING GROUP LENGTHS FROM',I4,' TO',I4,' BITS') */ if (pimp >= 2.f) { /* WRITE(KFILDO,255)CFEED,NEWBOXTP,IBXX2(JJ) */ /* 255 FORMAT(A1,/' *****************************************' */ /* 1 /' THE NUMBER OF NEWBOXES PER GROUP OF THE TOTAL', */ /* 2 I10,' FOR GROUP MAXSIZE PLUS 1 ='I10 */ /* 2 /' *****************************************') */ /* WRITE(KFILDO,256) (NEWBOXP(L),L=1,LX) */ /* 256 FORMAT(/' '20I6) */ /* ADJUST GROUP LENGTHS FOR MAXIMUM LENGTH OF JJ BITS. */ /* THE MIN PER GROUP AND THE NUMBER OF BITS REQUIRED */ /* PER GROUP ARE NOT CHANGED. THIS MAY MEAN THAT A */ /* GROUP HAS A MIN (OR REFERENCE) THAT IS NOT ZERO. */ /* THIS SHOULD NOT MATTER TO THE UNPACKER. */ lxnkp = *lx + newboxtp; /* LXNKP = THE NEW NUMBER OF BOXES */ if (lxnkp > *ndg) { /* DIMENSIONS NOT LARGE ENOUGH. PROBABLY AN ERROR */ /* OF SOME SORT. ABORT. */ /* WRITE(KFILDO,257)NDG,LXNPK */ /* 1 2 3 4 5 6 7 X */ /* 257 FORMAT(/' DIMENSIONS OF JMIN, ETC. IN REDUCE =',I8, */ /* 1 ' NOT LARGE ENOUGH FOR THE EXPANDED NUMBER OF', */ /* 2 ' GROUPS =',I8,'. ABORT REDUCE.') */ *ier = 715; goto L410; /* AN ABORT CAUSES THE CALLING PROGRAM TO REEXECUTE */ /* WITHOUT CALLING REDUCE. */ } lxn = lxnkp; /* LXN IS THE NUMBER OF THE BOX IN THE NEW SERIES BEING */ /* FILLED. IT DECREASES PER ITERATION. */ ibxx2m1 = ibxx2[jj] - 1; /* IBXX2M1 IS THE MAXIMUM NUMBER OF VALUES PER GROUP. */ for (l = *lx; l >= 1; --l) { /* THE VALUES IS NOV( ) REPRESENT THOSE VALUES + NOVREF. */ /* WHEN VALUES ARE MOVED TO ANOTHER BOX, EACH VALUE */ /* MOVED TO A NEW BOX REPRESENTS THAT VALUE + NOVREF. */ /* THIS HAS TO BE CONSIDERED IN MOVING VALUES. */ if (newboxp[l - 1] * (ibxx2m1 + *novref) + *novref > nov[l] + * novref) { /* IF THE ABOVE TEST IS MET, THEN MOVING IBXX2M1 VALUES */ /* FOR ALL NEW BOXES WILL LEAVE A NEGATIVE NUMBER FOR */ /* THE LAST BOX. NOT A TOLERABLE SITUATION. */ movmin = (nov[l] - newboxp[l - 1] * *novref) / newboxp[l - 1]; left = nov[l]; /* LEFT = THE NUMBER OF VALUES TO MOVE FROM THE ORIGINAL */ /* BOX TO EACH NEW BOX EXCEPT THE LAST. LEFT IS THE */ /* NUMBER LEFT TO MOVE. */ } else { movmin = ibxx2m1; /* MOVMIN VALUES CAN BE MOVED FOR EACH NEW BOX. */ left = nov[l]; /* LEFT IS THE NUMBER OF VALUES LEFT TO MOVE. */ } if (newboxp[l - 1] > 0) { if ((movmin + *novref) * newboxp[l - 1] + *novref <= nov[l] + *novref && (movmin + *novref) * (newboxp[l - 1] + 1) >= nov[l] + *novref) { goto L288; } else { /* ***D WRITE(KFILDO,287)L,MOVMIN,NOVREF,NEWBOXP(L),NOV(L) */ /* ***D287 FORMAT(/' AT 287 IN REDUCE--L,MOVMIN,NOVREF,', */ /* ***D 1 'NEWBOXP(L),NOV(L)',5I12 */ /* ***D 2 ' REDUCE ABORTED.') */ /* WRITE(KFILDO,2870) */ /* 2870 FORMAT(/' AN ERROR IN REDUCE ALGORITHM. ABORT REDUCE.') */ *ier = 714; goto L410; /* AN ABORT CAUSES THE CALLING PROGRAM TO REEXECUTE */ /* WITHOUT CALLING REDUCE. */ } } L288: i__1 = newboxp[l - 1] + 1; for (j = 1; j <= i__1; ++j) { /*move = min(movmin,left);*/ move = (movmin < left) ? movmin : left; jmin[lxn] = jmin[l]; jmax[lxn] = jmax[l]; lbit[lxn] = lbit[l]; nov[lxn] = move; --lxn; left -= move + *novref; /* THE MOVE OF MOVE VALUES REALLY REPRESENTS A MOVE OF */ /* MOVE + NOVREF VALUES. */ /* L290: */ } if (left != -(*novref)) { /* *** WRITE(KFILDO,292)L,LXN,MOVE,LXNKP,IBXX2(JJ),LEFT,NOV(L), */ /* *** 1 MOVMIN */ /* *** 292 FORMAT(' AT 292 IN REDUCE--L,LXN,MOVE,LXNKP,', */ /* *** 1 'IBXX2(JJ),LEFT,NOV(L),MOVMIN'/8I12) */ } /* L300: */ } *lx = lxnkp; /* LX IS NOW THE NEW NUMBER OF GROUPS. */ *kbit = jj; /* KBIT IS NOW THE NEW NUMBER OF BITS REQUIRED FOR PACKING */ /* GROUP LENGHTS. */ } /* WRITE(KFILDO,406)CFEED,LX */ /* 406 FORMAT(A1,/' *****************************************' */ /* 1 /' THE GROUP SIZES NOV( ) AFTER REDUCTION IN SIZE', */ /* 2 ' FOR'I10,' GROUPS', */ /* 3 /' *****************************************') */ /* WRITE(KFILDO,407) (NOV(J),J=1,LX) */ /* 407 FORMAT(/' '20I6) */ /* WRITE(KFILDO,408)CFEED,LX */ /* 408 FORMAT(A1,/' *****************************************' */ /* 1 /' THE GROUP MINIMA JMIN( ) AFTER REDUCTION IN SIZE', */ /* 2 ' FOR'I10,' GROUPS', */ /* 3 /' *****************************************') */ /* WRITE(KFILDO,409) (JMIN(J),J=1,LX) */ /* 409 FORMAT(/' '20I6) */ L410: if ( newbox != 0 ) free(newbox); if ( newboxp != 0 ) free(newboxp); return 0; } /* reduce_ */ g2clib-1.6.0/seekgb.c0000755002373300042670000000543012522400361014127 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" void seekgb(FILE *lugb,g2int iseek,g2int mseek,g2int *lskip,g2int *lgrib) //$$$ 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 // 2009-01-16 VUONG Changed lskip to 4 instead of sizof(g2int) // // USAGE: seekgb(FILE *lugb,g2int iseek,g2int 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 // //$$$ { g2int ret; g2int k,k4,ipos,nread,lim,start,vers,lengrib; int end; unsigned char *cbuf; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *lgrib=0; cbuf=(unsigned char *)malloc(mseek); nread=mseek; ipos=iseek; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // LOOP UNTIL GRIB MESSAGE IS FOUND while (*lgrib==0 && nread==mseek) { // READ PARTIAL SECTION ret=fseek(lugb,ipos,SEEK_SET); nread=fread(cbuf,sizeof(unsigned char),mseek,lugb); lim=nread-8; // LOOK FOR 'GRIB...' IN PARTIAL SECTION for (k=0;k<lim;k++) { gbit(cbuf,&start,(k+0)*8,4*8); gbit(cbuf,&vers,(k+7)*8,1*8); if (start==1196575042 && (vers==1 || vers==2)) { // LOOK FOR '7777' AT END OF GRIB MESSAGE if (vers == 1) gbit(cbuf,&lengrib,(k+4)*8,3*8); if (vers == 2) gbit(cbuf,&lengrib,(k+12)*8,4*8); ret=fseek(lugb,ipos+k+lengrib-4,SEEK_SET); // Hard code to 4 instead of sizeof(g2int) k4=fread(&end,4,1,lugb); if (k4 == 1 && end == 926365495) { //GRIB message found *lskip=ipos+k; *lgrib=lengrib; break; } } } ipos=ipos+lim; } free(cbuf); } g2clib-1.6.0/simpack.c0000755002373300042670000001447112522400361014323 0ustar Boi.Vuongglobal#include <stdlib.h> #include <math.h> #include "grib2.h" void simpack(g2float *fld,g2int ndpts,g2int *idrstmpl,unsigned char *cpack,g2int *lcpack) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: simpack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-11-06 // // ABSTRACT: This subroutine packs up a data field using the simple // packing algorithm as defined in the GRIB2 documention. It // also fills in GRIB2 Data Representation Template 5.0 with the // appropriate values. // // PROGRAM HISTORY LOG: // 2002-11-06 Gilbert // // USAGE: CALL simpack(fld,ndpts,idrstmpl,cpack,lcpack) // INPUT ARGUMENT LIST: // fld[] - Contains the data values to pack // ndpts - The number of data values in array fld[] // idrstmpl - Contains the array of values for Data Representation // Template 5.0 // [0] = Reference value - ignored on input // [1] = Binary Scale Factor // [2] = Decimal Scale Factor // [3] = Number of bits used to pack data, if value is // > 0 and <= 31. // If this input value is 0 or outside above range // then the num of bits is calculated based on given // data and scale factors. // [4] = Original field type - currently ignored on input // Data values assumed to be reals. // // OUTPUT ARGUMENT LIST: // idrstmpl - Contains the array of values for Data Representation // Template 5.0 // [0] = Reference value - set by simpack routine. // [1] = Binary Scale Factor - unchanged from input // [2] = Decimal Scale Factor - unchanged from input // [3] = Number of bits used to pack data, unchanged from // input if value is between 0 and 31. // If this input value is 0 or outside above range // then the num of bits is calculated based on given // data and scale factors. // [4] = Original field type - currently set = 0 on output. // Data values assumed to be reals. // cpack - The packed data field // lcpack - length of packed field starting at cpack. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$ { static g2int zero=0; g2int *ifld; g2int j,nbits,imin,imax,maxdif,nbittot,left; g2float bscale,dscale,rmax,rmin,temp; double maxnum; static g2float alog2=0.69314718; // ln(2.0) bscale=int_power(2.0,-idrstmpl[1]); dscale=int_power(10.0,idrstmpl[2]); if (idrstmpl[3] <= 0 || idrstmpl[3] > 31) nbits=0; else nbits=idrstmpl[3]; // // Find max and min values in the data // rmax=fld[0]; rmin=fld[0]; for (j=1;j<ndpts;j++) { if (fld[j] > rmax) rmax=fld[j]; if (fld[j] < rmin) rmin=fld[j]; } ifld=calloc(ndpts,sizeof(g2int)); // // If max and min values are not equal, pack up field. // If they are equal, we have a constant field, and the reference // value (rmin) is the value for each point in the field and // set nbits to 0. // if (rmin != rmax) { // // Determine which algorithm to use based on user-supplied // binary scale factor and number of bits. // if (nbits==0 && idrstmpl[1]==0) { // // No binary scaling and calculate minumum number of // bits in which the data will fit. // imin=(g2int)rint(rmin*dscale); imax=(g2int)rint(rmax*dscale); maxdif=imax-imin; temp=log((double)(maxdif+1))/alog2; nbits=(g2int)ceil(temp); rmin=(g2float)imin; // scale data for(j=0;j<ndpts;j++) ifld[j]=(g2int)rint(fld[j]*dscale)-imin; } else if (nbits!=0 && idrstmpl[1]==0) { // // Use minimum number of bits specified by user and // adjust binary scaling factor to accomodate data. // rmin=rmin*dscale; rmax=rmax*dscale; maxnum=int_power(2.0,nbits)-1; temp=log(maxnum/(rmax-rmin))/alog2; idrstmpl[1]=(g2int)ceil(-1.0*temp); bscale=int_power(2.0,-idrstmpl[1]); // scale data for (j=0;j<ndpts;j++) ifld[j]=(g2int)rint(((fld[j]*dscale)-rmin)*bscale); } else if (nbits==0 && idrstmpl[1]!=0) { // // Use binary scaling factor and calculate minumum number of // bits in which the data will fit. // rmin=rmin*dscale; rmax=rmax*dscale; maxdif=(g2int)rint((rmax-rmin)*bscale); temp=log((double)(maxdif+1))/alog2; nbits=(g2int)ceil(temp); // scale data for (j=0;j<ndpts;j++) ifld[j]=(g2int)rint(((fld[j]*dscale)-rmin)*bscale); } else if (nbits!=0 && idrstmpl[1]!=0) { // // Use binary scaling factor and use minumum number of // bits specified by user. Dangerous - may loose // information if binary scale factor and nbits not set // properly by user. // rmin=rmin*dscale; // scale data for (j=0;j<ndpts;j++) ifld[j]=(g2int)rint(((fld[j]*dscale)-rmin)*bscale); } // // Pack data, Pad last octet with Zeros, if necessary, // and calculate the length of the packed data in bytes // sbits(cpack,ifld+0,0,nbits,0,ndpts); nbittot=nbits*ndpts; left=8-(nbittot%8); if (left != 8) { sbit(cpack,&zero,nbittot,left); // Pad with zeros to fill Octet nbittot=nbittot+left; } *lcpack=nbittot/8; } else { nbits=0; *lcpack=0; } // // Fill in ref value and number of bits in Template 5.0 // //printf("SAGmkieee %f\n",rmin); mkieee(&rmin,idrstmpl+0,1); // ensure reference value is IEEE format //printf("SAGmkieee %ld\n",idrstmpl[0]); idrstmpl[3]=nbits; idrstmpl[4]=0; // original data were reals free(ifld); } g2clib-1.6.0/simunpack.c0000755002373300042670000000414612522400361014664 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include "grib2.h" g2int simunpack(unsigned char *cpack,g2int *idrstmpl,g2int ndpts,g2float *fld) ////$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: simunpack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-10-29 // // ABSTRACT: This subroutine unpacks a data field that was packed using a // simple packing algorithm as defined in the GRIB2 documention, // using info from the GRIB2 Data Representation Template 5.0. // // PROGRAM HISTORY LOG: // 2002-10-29 Gilbert // // USAGE: int simunpack(unsigned char *cpack,g2int *idrstmpl,g2int ndpts, // g2float *fld) // INPUT ARGUMENT LIST: // cpack - pointer to the packed data field. // idrstmpl - pointer to the array of values for Data Representation // Template 5.0 // ndpts - The number of data values to unpack // // OUTPUT ARGUMENT LIST: // fld - Contains the unpacked data values. fld must be allocated // with at least ndpts*sizeof(g2float) bytes before // calling this routine. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$// { g2int *ifld; g2int j,nbits,itype; g2float ref,bscale,dscale; rdieee(idrstmpl+0,&ref,1); bscale = int_power(2.0,idrstmpl[1]); dscale = int_power(10.0,-idrstmpl[2]); nbits = idrstmpl[3]; itype = idrstmpl[4]; ifld=(g2int *)calloc(ndpts,sizeof(g2int)); if ( ifld == 0 ) { fprintf(stderr,"Could not allocate space in simunpack.\n Data field NOT upacked.\n"); return(1); } // // if nbits equals 0, we have a constant field where the reference value // is the data value at each gridpoint // if (nbits != 0) { gbits(cpack,ifld,0,nbits,0,ndpts); for (j=0;j<ndpts;j++) { fld[j]=(((g2float)ifld[j]*bscale)+ref)*dscale; } } else { for (j=0;j<ndpts;j++) { fld[j]=ref; } } free(ifld); return(0); } g2clib-1.6.0/specpack.c0000644002373300042670000001004712522400361014455 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include <math.h> #include "grib2.h" void specpack(g2float *fld,g2int ndpts,g2int JJ,g2int KK,g2int MM, g2int *idrstmpl,unsigned char *cpack,g2int *lcpack) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: specpack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2002-12-19 // // ABSTRACT: This subroutine packs a spectral data field using the complex // packing algorithm for spherical harmonic data as // defined in the GRIB2 Data Representation Template 5.51. // // PROGRAM HISTORY LOG: // 2002-12-19 Gilbert // // USAGE: void specpack(g2float *fld,g2int ndpts,g2int JJ,g2int KK,g2int MM, // g2int *idrstmpl,insigned char *cpack,g2int *lcpack) // INPUT ARGUMENT LIST: // fld[] - Contains the packed data values // ndpts - The number of data values to pack // JJ - J - pentagonal resolution parameter // KK - K - pentagonal resolution parameter // MM - M - pentagonal resolution parameter // idrstmpl - Contains the array of values for Data Representation // Template 5.51 // // OUTPUT ARGUMENT LIST: // cpack - The packed data field (character*1 array) // lcpack - length of packed field cpack(). // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: IBM SP // //$$$ { g2int *ifld,tmplsim[5]; g2float bscale,dscale,*unpk,*tfld; g2float *pscale,tscale; g2int Js,Ks,Ms,Ts,Ns,inc,incu,incp,n,Nm,m,ipos; bscale = int_power(2.0,-idrstmpl[1]); dscale = int_power(10.0,idrstmpl[2]); Js=idrstmpl[5]; Ks=idrstmpl[6]; Ms=idrstmpl[7]; Ts=idrstmpl[8]; // // Calculate Laplacian scaling factors for each possible wave number. // pscale=(g2float *)malloc((JJ+MM)*sizeof(g2float)); tscale=(g2float)idrstmpl[4]*1E-6; for (n=Js;n<=JJ+MM;n++) pscale[n]=pow((g2float)(n*(n+1)),tscale); // // Separate spectral coeffs into two lists; one to contain unpacked // values within the sub-spectrum Js, Ks, Ms, and the other with values // outside of the sub-spectrum to be packed. // tfld=(g2float *)malloc(ndpts*sizeof(g2float)); unpk=(g2float *)malloc(ndpts*sizeof(g2float)); ifld=(g2int *)malloc(ndpts*sizeof(g2int)); inc=0; incu=0; incp=0; for (m=0;m<=MM;m++) { Nm=JJ; // triangular or trapezoidal if ( KK == JJ+MM ) Nm=JJ+m; // rhombodial Ns=Js; // triangular or trapezoidal if ( Ks == Js+Ms ) Ns=Js+m; // rhombodial for (n=m;n<=Nm;n++) { if (n<=Ns && m<=Ms) { // save unpacked value unpk[incu++]=fld[inc++]; // real part unpk[incu++]=fld[inc++]; // imaginary part } else { // Save value to be packed and scale // Laplacian scale factor tfld[incp++]=fld[inc++]*pscale[n]; // real part tfld[incp++]=fld[inc++]*pscale[n]; // imaginary part } } } free(pscale); if (incu != Ts) { printf("specpack: Incorrect number of unpacked values %d given:\n",(int)Ts); printf("specpack: Resetting idrstmpl[8] to %d\n",(int)incu); Ts=incu; } // // Add unpacked values to the packed data array in 32-bit IEEE format // mkieee(unpk,(g2int *)cpack,Ts); ipos=4*Ts; // // Scale and pack the rest of the coefficients // tmplsim[1]=idrstmpl[1]; tmplsim[2]=idrstmpl[2]; tmplsim[3]=idrstmpl[3]; simpack(tfld,ndpts-Ts,tmplsim,cpack+ipos,lcpack); *lcpack=(*lcpack)+ipos; // // Fill in Template 5.51 // idrstmpl[0]=tmplsim[0]; idrstmpl[1]=tmplsim[1]; idrstmpl[2]=tmplsim[2]; idrstmpl[3]=tmplsim[3]; idrstmpl[8]=Ts; idrstmpl[9]=1; // Unpacked spectral data is 32-bit IEEE free(tfld); free(unpk); free(ifld); return; } g2clib-1.6.0/specunpack.c0000755002373300042670000000751012522400361015024 0ustar Boi.Vuongglobal#include <stdio.h> #include <stdlib.h> #include <math.h> #include "grib2.h" g2int specunpack(unsigned char *cpack,g2int *idrstmpl,g2int ndpts,g2int JJ, g2int KK, g2int MM, g2float *fld) //$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . // SUBPROGRAM: specunpack // PRGMMR: Gilbert ORG: W/NP11 DATE: 2000-06-21 // // ABSTRACT: This subroutine unpacks a spectral data field that was packed // using the complex packing algorithm for spherical harmonic data as // defined in the GRIB2 documention, // using info from the GRIB2 Data Representation Template 5.51. // // PROGRAM HISTORY LOG: // 2000-06-21 Gilbert // // USAGE: int specunpack(unsigned char *cpack,g2int *idrstmpl, // g2int ndpts,g2int JJ,g2int KK,g2int MM,g2float *fld) // INPUT ARGUMENT LIST: // cpack - pointer to the packed data field. // idrstmpl - pointer to the array of values for Data Representation // Template 5.51 // ndpts - The number of data values to unpack (real and imaginary parts) // JJ - J - pentagonal resolution parameter // KK - K - pentagonal resolution parameter // MM - M - pentagonal resolution parameter // // OUTPUT ARGUMENT LIST: // fld() - Contains the unpacked data values. fld must be allocated // with at least ndpts*sizeof(g2float) bytes before // calling this routine. // // REMARKS: None // // ATTRIBUTES: // LANGUAGE: C // MACHINE: // //$$$ { g2int *ifld,j,iofst,nbits; g2float ref,bscale,dscale,*unpk; g2float *pscale,tscale; g2int Js,Ks,Ms,Ts,Ns,Nm,n,m; g2int inc,incu,incp; rdieee(idrstmpl+0,&ref,1); bscale = int_power(2.0,idrstmpl[1]); dscale = int_power(10.0,-idrstmpl[2]); nbits = idrstmpl[3]; Js=idrstmpl[5]; Ks=idrstmpl[6]; Ms=idrstmpl[7]; Ts=idrstmpl[8]; if (idrstmpl[9] == 1) { // unpacked floats are 32-bit IEEE unpk=(g2float *)malloc(ndpts*sizeof(g2float)); ifld=(g2int *)malloc(ndpts*sizeof(g2int)); gbits(cpack,ifld,0,32,0,Ts); iofst=32*Ts; rdieee(ifld,unpk,Ts); // read IEEE unpacked floats gbits(cpack,ifld,iofst,nbits,0,ndpts-Ts); // unpack scaled data // // Calculate Laplacian scaling factors for each possible wave number. // pscale=(g2float *)malloc((JJ+MM+1)*sizeof(g2float)); tscale=(g2float)idrstmpl[4]*1E-6; for (n=Js;n<=JJ+MM;n++) pscale[n]=pow((g2float)(n*(n+1)),-tscale); // // Assemble spectral coeffs back to original order. // inc=0; incu=0; incp=0; for (m=0;m<=MM;m++) { Nm=JJ; // triangular or trapezoidal if ( KK == JJ+MM ) Nm=JJ+m; // rhombodial Ns=Js; // triangular or trapezoidal if ( Ks == Js+Ms ) Ns=Js+m; // rhombodial for (n=m;n<=Nm;n++) { if (n<=Ns && m<=Ms) { // grab unpacked value fld[inc++]=unpk[incu++]; // real part fld[inc++]=unpk[incu++]; // imaginary part } else { // Calc coeff from packed value fld[inc++]=(((g2float)ifld[incp++]*bscale)+ref)* dscale*pscale[n]; // real part fld[inc++]=(((g2float)ifld[incp++]*bscale)+ref)* dscale*pscale[n]; // imaginary part } } } free(pscale); free(unpk); free(ifld); } else { printf("specunpack: Cannot handle 64 or 128-bit floats.\n"); for (j=0;j<ndpts;j++) fld[j]=0.0; return -3; } return 0; } 07070100000003000081A400000000000000000000000163B39B3400001B71000000000000000000000000000000000000002D00000000g2clib-1672715060.88a25f7/g2clib-64bit.patchdiff -up g2clib-1.6.0_orig/g2_addfield.c g2clib-1.6.0/g2_addfield.c --- g2clib-1.6.0_orig/g2_addfield.c 2015-05-06 13:54:24.000000000 +0200 +++ g2clib-1.6.0/g2_addfield.c 2017-08-13 10:02:58.232596592 +0200 @@ -1,3 +1,4 @@ +#include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include "grib2.h" @@ -190,8 +191,8 @@ g2int g2_addfield(unsigned char *cgrib,g // total length, then there is a problem. if ( len > lencurr ) { printf("g2_addfield: Section byte counts don''t add to total.\n"); - printf("g2_addfield: Sum of section byte counts = %ld\n",len); - printf("g2_addfield: Total byte count in Section 0 = %ld\n",lencurr); + printf("g2_addfield: Sum of section byte counts = %"PRId32"\n",len); + printf("g2_addfield: Total byte count in Section 0 = %"PRId32"\n",lencurr); ierr=-3; return(ierr); } @@ -392,7 +393,7 @@ g2int g2_addfield(unsigned char *cgrib,g } #endif /* USE_PNG */ else { - printf("g2_addfield: Data Representation Template 5.%ld not yet implemented.\n",idrsnum); + printf("g2_addfield: Data Representation Template 5.%"PRId32" not yet implemented.\n",idrsnum); ierr=-7; return(ierr); } diff -up g2clib-1.6.0_orig/g2_addgrid.c g2clib-1.6.0/g2_addgrid.c --- g2clib-1.6.0_orig/g2_addgrid.c 2015-05-06 13:54:24.000000000 +0200 +++ g2clib-1.6.0/g2_addgrid.c 2017-08-13 10:02:58.233596570 +0200 @@ -1,3 +1,4 @@ +#include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include "grib2.h" @@ -125,8 +126,8 @@ g2int g2_addgrid(unsigned char *cgrib,g2 // total length, then there is a problem. if ( len > lencurr ) { printf("g2_addgrid: Section byte counts don''t add to total.\n"); - printf("g2_addgrid: Sum of section byte counts = %ld\n",len); - printf("g2_addgrid: Total byte count in Section 0 = %ld\n",lencurr); + printf("g2_addgrid: Sum of section byte counts = %"PRId32"\n",len); + printf("g2_addgrid: Total byte count in Section 0 = %"PRId32"\n",lencurr); ierr=-3; return(ierr); } diff -up g2clib-1.6.0_orig/g2_addlocal.c g2clib-1.6.0/g2_addlocal.c --- g2clib-1.6.0_orig/g2_addlocal.c 2015-05-06 13:54:24.000000000 +0200 +++ g2clib-1.6.0/g2_addlocal.c 2017-08-13 10:02:58.233596570 +0200 @@ -1,3 +1,4 @@ +#include <inttypes.h> #include <stdio.h> #include "grib2.h" @@ -102,8 +103,8 @@ g2int g2_addlocal(unsigned char *cgrib,u // total length, then there is a problem. if ( len > lencurr ) { printf("g2_addlocal: Section byte counts don't add to total.\n"); - printf("g2_addlocal: Sum of section byte counts = %ld\n",len); - printf("g2_addlocal: Total byte count in Section 0 = %ld\n",lencurr); + printf("g2_addlocal: Sum of section byte counts = %"PRId32"\n",len); + printf("g2_addlocal: Total byte count in Section 0 = %"PRId32"\n",lencurr); ierr=-3; return(ierr); } @@ -113,7 +114,7 @@ g2int g2_addlocal(unsigned char *cgrib,u // if ( (isecnum!=1) && (isecnum!=7) ) { printf("g2_addlocal: Section 2 can only be added after Section 1 or Section 7.\n"); - printf("g2_addlocal: Section %ld was the last found in given GRIB message.\n",isecnum); + printf("g2_addlocal: Section %"PRId32" was the last found in given GRIB message.\n",isecnum); ierr=-4; return(ierr); } diff -up g2clib-1.6.0_orig/g2_getfld.c g2clib-1.6.0/g2_getfld.c --- g2clib-1.6.0_orig/g2_getfld.c 2015-05-06 13:54:25.000000000 +0200 +++ g2clib-1.6.0/g2_getfld.c 2017-08-13 10:02:58.234596548 +0200 @@ -1,3 +1,4 @@ +#include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include "grib2.h" @@ -345,12 +346,12 @@ g2int g2_getfld(unsigned char *cgrib,g2i iofst=iofst+32; gbit(cgrib,&isecnum,iofst,8); // Get Section number iofst=iofst+8; - //printf(" lensec= %ld secnum= %ld \n",lensec,isecnum); + //printf(" lensec= %"PRId32" secnum= %"PRId32" \n",lensec,isecnum); // // Check to see if section number is valid // if ( isecnum<1 || isecnum>7 ) { - printf("g2_getfld: Unrecognized Section Encountered=%ld\n",isecnum); + printf("g2_getfld: Unrecognized Section Encountered=%"PRId32"\n",isecnum); ierr=8; return(ierr); } @@ -543,8 +544,8 @@ g2int g2_getfld(unsigned char *cgrib,g2i // If exited from above loop, the end of the GRIB message was reached // before the requested field was found. // - printf("g2_getfld: GRIB message contained %ld different fields.\n",numfld); - printf("g2_getfld: The request was for field %ld.\n",ifldnum); + printf("g2_getfld: GRIB message contained %"PRId32" different fields.\n",numfld); + printf("g2_getfld: The request was for field %"PRId32".\n",ifldnum); ierr=6; return(ierr); diff -up g2clib-1.6.0_orig/g2_gribend.c g2clib-1.6.0/g2_gribend.c --- g2clib-1.6.0_orig/g2_gribend.c 2015-05-06 13:54:25.000000000 +0200 +++ g2clib-1.6.0/g2_gribend.c 2017-08-13 10:02:58.234596548 +0200 @@ -1,3 +1,4 @@ +#include <inttypes.h> #include <stdio.h> #include "grib2.h" @@ -97,7 +98,7 @@ g2int g2_gribend(unsigned char *cgrib) // if ( isecnum != 7 ) { printf("g2_gribend: Section 8 can only be added after Section 7.\n"); - printf("g2_gribend: Section %ld was the last found in given GRIB message.\n",isecnum); + printf("g2_gribend: Section %"PRId32" was the last found in given GRIB message.\n",isecnum); ierr=-4; return (ierr); } diff -up g2clib-1.6.0_orig/g2_info.c g2clib-1.6.0/g2_info.c --- g2clib-1.6.0_orig/g2_info.c 2015-05-06 13:54:25.000000000 +0200 +++ g2clib-1.6.0/g2_info.c 2017-08-13 10:02:58.234596548 +0200 @@ -1,3 +1,4 @@ +#include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include "grib2.h" @@ -178,7 +179,7 @@ g2int g2_info(unsigned char *cgrib,g2int (*numfields)++; } else { - printf("g2_info: Invalid section number found in GRIB message: %ld\n" ,isecnum); + printf("g2_info: Invalid section number found in GRIB message: %"PRId32"\n" ,isecnum); ierr=6; return(ierr); } diff -up g2clib-1.6.0_orig/grib2.h g2clib-1.6.0/grib2.h --- g2clib-1.6.0_orig/grib2.h 2016-01-22 13:27:13.000000000 +0100 +++ g2clib-1.6.0/grib2.h 2017-08-13 10:02:58.235596526 +0200 @@ -1,5 +1,6 @@ #ifndef _grib2_H #define _grib2_H +#include<inttypes.h> #include<stdio.h> #define G2_VERSION "g2clib-1.6.0" @@ -151,13 +152,8 @@ // that holds the data. */ -#ifdef __64BIT__ -typedef int g2int; -typedef unsigned int g2intu; -#else -typedef long g2int; -typedef unsigned long g2intu; -#endif +typedef int32_t g2int; +typedef uint32_t g2intu; typedef float g2float; struct gtemplate { 07070100000004000081A400000000000000000000000163B39B34000003DA000000000000000000000000000000000000002E00000000g2clib-1672715060.88a25f7/g2clib-degrib.patchdiff -up g2clib-1.6.0.p123/gridtemplates.c g2clib-1.6.0.p1234/gridtemplates.c --- g2clib-1.6.0.p123/gridtemplates.c 2017-08-13 10:50:40.668001879 +0200 +++ g2clib-1.6.0.p1234/gridtemplates.c 2017-08-13 10:52:24.579434531 +0200 @@ -24,11 +24,11 @@ const struct gridtemplate templatesgrid[ {140, 17, 0, {1,1,4,1,4,1,4,4,4,-4,4,4,4,1,4,4,1} }, // // 3.10: Mercator - {10, 19, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,-4,4,1,4,4,4} }, + {10, 19, 0, {1,1,4,1,4,1,4,4,4,-4,-4,1,-4,-4,-4,1,4,4,4} }, // 3.20: Polar Stereographic Projection - {20, 18, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1} }, + {20, 18, 0, {1,1,4,1,4,1,4,4,4,-4,-4,1,-4,-4,4,4,1,1} }, // 3.30: Lambert Conformal - {30, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1,-4,-4,-4,4} }, + {30, 22, 0, {1,1,4,1,4,1,4,4,4,-4,-4,1,-4,-4,4,4,1,1,-4,-4,-4,-4} }, // 3.31: Albers equal area {31, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1,-4,-4,-4,4} }, // 3.40: Guassian Lat/Lon 07070100000005000081A400000000000000000000000163B39B34000001E1000000000000000000000000000000000000002F00000000g2clib-1672715060.88a25f7/g2clib-jasper2.patchdiff -up g2clib-1.6.0.p1234/enc_jpeg2000.c g2clib-1.6.0.p12345/enc_jpeg2000.c --- g2clib-1.6.0.p1234/enc_jpeg2000.c 2017-08-13 10:52:12.990720854 +0200 +++ g2clib-1.6.0.p12345/enc_jpeg2000.c 2017-08-13 10:55:41.220584631 +0200 @@ -121,7 +121,9 @@ int enc_jpeg2000(unsigned char *cin,g2in image.clrspc_=JAS_CLRSPC_SGRAY; /* grayscale Image */ image.cmprof_=0; #endif +#if JAS_VERSION_MAJOR == 1 image.inmem_=1; +#endif cmpt.tlx_=0; cmpt.tly_=0; 07070100000006000081A400000000000000000000000163B39B3400000657000000000000000000000000000000000000002900000000g2clib-1672715060.88a25f7/g2clib-msg.txtDate: Fri, 24 Aug 2007 08:03:05 -0400 From: "Justin Cooke" <justin.cooke@noaa.gov> To: pertusus@free.fr Subject: Re: [pmb.dataflow #1013] grib2 related programs license Reply-To: ncep.pmb.dataflow@noaa.gov X-Loop: WREQ 2 Status: RO Content-Length: 1358 Lines: 49 Your request #1013 was updated by justin.cooke: Hi Pat, Yes all code available on the NCEP website, including cnvgrib, is public domain. I will pass along the request to add the public domain message to the documentation of cnvgrib. Justin Cooke NCEP Central Operations >>>>>>>>>>>>>>>>>> Original Message >>>>>>>>>>>>>>>>>> >From: Patrice Dumas <pertusus@free.fr> >Subject: grib2 related programs license >To: NCEP.List.PMB-PCSP@noaa.gov Hello, It is possible that I am not adressing this mail to the right people, but this seems to me to be the simplest way to reach the right people. On http://www.nco.ncep.noaa.gov/pmb/codes/GRIB2/ there are some codes, but the license isn't stated anywhere. It could mean Public Domain if there was no author mention, but there is some mention of the authors, like PRGMMR: Gilbert (I only checked g2clib and g2lib, I don't know for the other softwares). On the disclaimer page: http://www.weather.gov/disclaimer.php there is no reference to the programming codes found on the site, only to data and text. My feeling is that these codes are public domain, but I prefer to ask to be sure. Also if it is true, maybe you could mention it in the README? Cordially, -- Pat >>>>>>>>>>>>>>>>>> Action Log >>>>>>>>>>>>>>>>>> ====================== Updated/Mailed by justin.cooke Aug 24 8:3:4 2007 (1187956984) 07070100000007000081A400000000000000000000000163B39B3400000246000000000000000000000000000000000000003100000000g2clib-1672715060.88a25f7/g2clib-simunpack.patchdiff -up g2clib-1.6.0.p12/simunpack.c g2clib-1.6.0.p123/simunpack.c --- g2clib-1.6.0.p12/simunpack.c 2017-08-13 10:24:02.266764550 +0200 +++ g2clib-1.6.0.p123/simunpack.c 2017-08-13 10:50:49.881774231 +0200 @@ -49,7 +49,7 @@ g2int simunpack(unsigned char *cpack,g2i nbits = idrstmpl[3]; itype = idrstmpl[4]; - ifld=(g2int *)calloc(ndpts,sizeof(g2int)); + ifld=(g2int *)calloc((ndpts ? ndpts : 1),sizeof(g2int)); if ( ifld == 0 ) { fprintf(stderr,"Could not allocate space in simunpack.\n Data field NOT upacked.\n"); return(1); 07070100000008000081A400000000000000000000000163B39B3400007F54000000000000000000000000000000000000003100000000g2clib-1672715060.88a25f7/g2clib-templates.patchdiff -up g2clib-1.6.0.p1/drstemplates.c g2clib-1.6.0.p12/drstemplates.c --- g2clib-1.6.0.p1/drstemplates.c 2017-08-13 10:17:37.479288682 +0200 +++ g2clib-1.6.0.p12/drstemplates.c 2017-08-13 10:26:59.958196881 +0200 @@ -2,6 +2,29 @@ #include "grib2.h" #include "drstemplates.h" +const struct drstemplate templatesdrs[MAXDRSTEMP] = { + // 5.0: Grid point data - Simple Packing + { 0, 5, 0, {4,-2,-2,1,1} }, + // 5.2: Grid point data - Complex Packing + { 2, 16, 0, {4,-2,-2,1,1,1,1,4,4,4,1,1,4,1,4,1} }, + // 5.3: Grid point data - Complex Packing and spatial differencing + { 3, 18, 0, {4,-2,-2,1,1,1,1,4,4,4,1,1,4,1,4,1,1,1} }, + // 5.50: Spectral Data - Simple Packing + { 50, 5, 0, {4,-2,-2,1,4} }, + // 5.51: Spherical Harmonics data - Complex packing + { 51, 10, 0, {4,-2,-2,1,-4,2,2,2,4,1} }, +// // 5.1: Matrix values at gridpoint - Simple packing +// { 1, 15, 1, {4,-2,-2,1,1,1,4,2,2,1,1,1,1,1,1} }, + // 5.40: Grid point data - JPEG2000 encoding + { 40, 7, 0, {4,-2,-2,1,1,1,1} }, + // 5.41: Grid point data - PNG encoding + { 41, 5, 0, {4,-2,-2,1,1} }, + // 5.40000: Grid point data - JPEG2000 encoding + { 40000, 7, 0, {4,-2,-2,1,1,1,1} }, + // 5.40010: Grid point data - PNG encoding + { 40010, 5, 0, {4,-2,-2,1,1} } +} ; + g2int getdrsindex(g2int number) /*!$$$ SUBPROGRAM DOCUMENTATION BLOCK ! . . . . diff -up g2clib-1.6.0.p1/drstemplates.h g2clib-1.6.0.p12/drstemplates.h --- g2clib-1.6.0.p1/drstemplates.h 2017-08-13 10:17:37.479288682 +0200 +++ g2clib-1.6.0.p12/drstemplates.h 2017-08-13 10:26:38.492728755 +0200 @@ -42,28 +42,8 @@ g2int mapdrs[MAXDRSMAPLEN]; }; - const struct drstemplate templatesdrs[MAXDRSTEMP] = { - // 5.0: Grid point data - Simple Packing - { 0, 5, 0, {4,-2,-2,1,1} }, - // 5.2: Grid point data - Complex Packing - { 2, 16, 0, {4,-2,-2,1,1,1,1,4,4,4,1,1,4,1,4,1} }, - // 5.3: Grid point data - Complex Packing and spatial differencing - { 3, 18, 0, {4,-2,-2,1,1,1,1,4,4,4,1,1,4,1,4,1,1,1} }, - // 5.50: Spectral Data - Simple Packing - { 50, 5, 0, {4,-2,-2,1,4} }, - // 5.51: Spherical Harmonics data - Complex packing - { 51, 10, 0, {4,-2,-2,1,-4,2,2,2,4,1} }, -// // 5.1: Matrix values at gridpoint - Simple packing -// { 1, 15, 1, {4,-2,-2,1,1,1,4,2,2,1,1,1,1,1,1} }, - // 5.40: Grid point data - JPEG2000 encoding - { 40, 7, 0, {4,-2,-2,1,1,1,1} }, - // 5.41: Grid point data - PNG encoding - { 41, 5, 0, {4,-2,-2,1,1} }, - // 5.40000: Grid point data - JPEG2000 encoding - { 40000, 7, 0, {4,-2,-2,1,1,1,1} }, - // 5.40010: Grid point data - PNG encoding - { 40010, 5, 0, {4,-2,-2,1,1} } - } ; + extern const struct drstemplate templatesdrs[]; + g2int getdrsindex(g2int number); #endif /* _drstemplates_H */ Binary files g2clib-1.6.0.p1/grib2c.doc.gz and g2clib-1.6.0.p12/grib2c.doc.gz differ diff -up g2clib-1.6.0.p1/gridtemplates.c g2clib-1.6.0.p12/gridtemplates.c --- g2clib-1.6.0.p1/gridtemplates.c 2017-08-13 10:17:37.481288632 +0200 +++ g2clib-1.6.0.p12/gridtemplates.c 2017-08-13 10:41:53.079066944 +0200 @@ -2,6 +2,75 @@ #include "grib2.h" #include "gridtemplates.h" +const struct gridtemplate templatesgrid[MAXGRIDTEMP] = { + // 3.0: Lat/Lon grid + { 0, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} }, + // 3.1: Rotated Lat/Lon grid + { 1, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4} }, + // 3.2: Stretched Lat/Lon grid + { 2, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,-4} }, + // 3.3: Stretched & Rotated Lat/Lon grid + { 3, 25, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4,-4,4,-4} }, +// Added GDT 3.4,3.5 (08/05/2013) + // 3.4: Variable resolution Latitude/Longitude + { 4, 13, 1, {1,1,4,1,4,1,4,4,4,4,4,1,1} }, + // 3.5: Variable resolution rotate Latitude/Longitude + { 5, 16, 1, {1,1,4,1,4,1,4,4,4,4,4,1,1,-4,4,4} }, + // 3.12: Transverse Mercator + {12, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,1,4,4,-4,-4,-4,-4} }, + // 3.101: General unstructured grid + {101, 4, 0, {1,4,1,-4} }, + // 3.140: Lambert Azimuthal Equal Area Projection + {140, 17, 0, {1,1,4,1,4,1,4,4,4,-4,4,4,4,1,4,4,1} }, +// + // 3.10: Mercator + {10, 19, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,-4,4,1,4,4,4} }, + // 3.20: Polar Stereographic Projection + {20, 18, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1} }, + // 3.30: Lambert Conformal + {30, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1,-4,-4,-4,4} }, + // 3.31: Albers equal area + {31, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1,-4,-4,-4,4} }, + // 3.40: Guassian Lat/Lon + {40, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} }, + // 3.41: Rotated Gaussian Lat/Lon + {41, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4} }, + // 3.42: Stretched Gaussian Lat/Lon + {42, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,-4} }, + // 3.43: Stretched and Rotated Gaussian Lat/Lon + {43, 25, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4,-4,4,-4} }, + // 3.50: Spherical Harmonic Coefficients + {50, 5, 0, {4,4,4,1,1} }, + // 3.51: Rotated Spherical Harmonic Coefficients + {51, 8, 0, {4,4,4,1,1,-4,4,4} }, + // 3.52: Stretched Spherical Harmonic Coefficients + {52, 8, 0, {4,4,4,1,1,-4,4,-4} }, + // 3.53: Stretched and Rotated Spherical Harmonic Coefficients + {53, 11, 0, {4,4,4,1,1,-4,4,4,-4,4,-4} }, + // 3.90: Space View Perspective or orthographic + {90, 21, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,4,4,4,4,1,4,4,4,4} }, + // 3.100: Triangular grid based on an icosahedron + {100, 11, 0, {1,1,2,1,-4,4,4,1,1,1,4} }, + // 3.110: Equatorial Azimuthal equidistant + {110, 16, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,4,4,1,1} }, + // 3.120: Azimuth-range projection + {120, 7, 1, {4,4,-4,4,4,4,1} }, + // 3.204: Curvilinear Orthogonal Grid + {204, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} }, + // 3.32768: Rot Lat/Lon E-grid (Arakawa) + {32768, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} }, + // 3.32769: Rot Lat/Lon Non-E Staggered grid (Arakawa) + {32769, 21, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,4,4} }, + // 3.1000: Cross Section Grid + {1000, 20, 1, {1,1,4,1,4,1,4,4,4,4,-4,4,1,4,4,1,2,1,1,2} }, + // 3.1100: Hovmoller Diagram Grid + {1100, 28, 0, {1,1,4,1,4,1,4,4,4,4,-4,4,1,-4,4,1,4,1,-4,1,1,-4,2,1,1,1,1,1} }, + // 3.1200: Time Section Grid + {1200, 16, 1, {4,1,-4,1,1,-4,2,1,1,1,1,1,2,1,1,2} } + +} ; + + g2int getgridindex(g2int number) /*!$$$ SUBPROGRAM DOCUMENTATION BLOCK ! . . . . diff -up g2clib-1.6.0.p1/gridtemplates.h g2clib-1.6.0.p12/gridtemplates.h --- g2clib-1.6.0.p1/gridtemplates.h 2017-08-13 10:17:37.481288632 +0200 +++ g2clib-1.6.0.p12/gridtemplates.h 2017-08-13 10:30:23.584151390 +0200 @@ -49,73 +49,8 @@ g2int mapgrid[MAXGRIDMAPLEN]; }; - const struct gridtemplate templatesgrid[MAXGRIDTEMP] = { - // 3.0: Lat/Lon grid - { 0, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} }, - // 3.1: Rotated Lat/Lon grid - { 1, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4} }, - // 3.2: Stretched Lat/Lon grid - { 2, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,-4} }, - // 3.3: Stretched & Rotated Lat/Lon grid - { 3, 25, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4,-4,4,-4} }, -// Added GDT 3.4,3.5 (08/05/2013) - // 3.4: Variable resolution Latitude/Longitude - { 4, 13, 1, {1,1,4,1,4,1,4,4,4,4,4,1,1} }, - // 3.5: Variable resolution rotate Latitude/Longitude - { 5, 16, 1, {1,1,4,1,4,1,4,4,4,4,4,1,1,-4,4,4} }, - // 3.12: Transverse Mercator - {12, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,1,4,4,-4,-4,-4,-4} }, - // 3.101: General unstructured grid - {101, 4, 0, {1,4,1,-4} }, - // 3.140: Lambert Azimuthal Equal Area Projection - {140, 17, 0, {1,1,4,1,4,1,4,4,4,-4,4,4,4,1,4,4,1} }, -// - // 3.10: Mercator - {10, 19, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,-4,4,1,4,4,4} }, - // 3.20: Polar Stereographic Projection - {20, 18, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1} }, - // 3.30: Lambert Conformal - {30, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1,-4,-4,-4,4} }, - // 3.31: Albers equal area - {31, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1,-4,-4,-4,4} }, - // 3.40: Guassian Lat/Lon - {40, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} }, - // 3.41: Rotated Gaussian Lat/Lon - {41, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4} }, - // 3.42: Stretched Gaussian Lat/Lon - {42, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,-4} }, - // 3.43: Stretched and Rotated Gaussian Lat/Lon - {43, 25, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4,-4,4,-4} }, - // 3.50: Spherical Harmonic Coefficients - {50, 5, 0, {4,4,4,1,1} }, - // 3.51: Rotated Spherical Harmonic Coefficients - {51, 8, 0, {4,4,4,1,1,-4,4,4} }, - // 3.52: Stretched Spherical Harmonic Coefficients - {52, 8, 0, {4,4,4,1,1,-4,4,-4} }, - // 3.53: Stretched and Rotated Spherical Harmonic Coefficients - {53, 11, 0, {4,4,4,1,1,-4,4,4,-4,4,-4} }, - // 3.90: Space View Perspective or orthographic - {90, 21, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,4,4,4,4,1,4,4,4,4} }, - // 3.100: Triangular grid based on an icosahedron - {100, 11, 0, {1,1,2,1,-4,4,4,1,1,1,4} }, - // 3.110: Equatorial Azimuthal equidistant - {110, 16, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,4,4,1,1} }, - // 3.120: Azimuth-range projection - {120, 7, 1, {4,4,-4,4,4,4,1} }, - // 3.204: Curvilinear Orthogonal Grid - {204, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} }, - // 3.32768: Rot Lat/Lon E-grid (Arakawa) - {32768, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} }, - // 3.32769: Rot Lat/Lon Non-E Staggered grid (Arakawa) - {32769, 21, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,4,4} }, - // 3.1000: Cross Section Grid - {1000, 20, 1, {1,1,4,1,4,1,4,4,4,4,-4,4,1,4,4,1,2,1,1,2} }, - // 3.1100: Hovmoller Diagram Grid - {1100, 28, 0, {1,1,4,1,4,1,4,4,4,4,-4,4,1,-4,4,1,4,1,-4,1,1,-4,2,1,1,1,1,1} }, - // 3.1200: Time Section Grid - {1200, 16, 1, {4,1,-4,1,1,-4,2,1,1,1,1,1,2,1,1,2} } - - } ; + extern const struct gridtemplate templatesgrid[]; + g2int getgridindex(g2int number); #endif /* _gridtemplates_H */ diff -up g2clib-1.6.0.p1/pdstemplates.c g2clib-1.6.0.p12/pdstemplates.c --- g2clib-1.6.0.p1/pdstemplates.c 2017-08-13 10:17:37.482288608 +0200 +++ g2clib-1.6.0.p12/pdstemplates.c 2017-08-13 10:47:53.643134973 +0200 @@ -2,6 +2,179 @@ #include "grib2.h" #include "pdstemplates.h" +const struct pdstemplate templatespds[MAXPDSTEMP] = { + // 4.0: Analysis or Forecast at Horizontal Level/Layer + // at a point in time + {0,15,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, + // 4.1: Individual Ensemble Forecast at Horizontal Level/Layer + // at a point in time + {1,18,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, + // 4.2: Derived Fcst based on whole Ensemble at Horiz Level/Layer + // at a point in time + {2,17,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1} }, + // 4.3: Derived Fcst based on Ensemble cluster over rectangular + // area at Horiz Level/Layer at a point in time + {3,31,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,-4,4,4,1,-1,4,-1,4} }, + // 4.4: Derived Fcst based on Ensemble cluster over circular + // area at Horiz Level/Layer at a point in time + {4,30,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,4,4,1,-1,4,-1,4} }, + // 4.5: Probablility Forecast at Horiz Level/Layer + // at a point in time + {5,22,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,-1,-4,-1,-4} }, + // 4.6: Percentile Forecast at Horiz Level/Layer + // at a point in time + {6,16,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1} }, + // 4.7: Analysis or Forecast Error at Horizontal Level/Layer + // at a point in time + {7,15,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, + // 4.8: Ave/Accum/etc... at Horiz Level/Layer + // in a time interval + {8,29,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, + // 4.9: Probablility Forecast at Horiz Level/Layer + // in a time interval + {9,36,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,-1,-4,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, + // 4.10: Percentile Forecast at Horiz Level/Layer + // in a time interval + {10,30,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, + // 4.11: Individual Ensemble Forecast at Horizontal Level/Layer + // in a time interval + {11,32,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, + // 4.12: Derived Fcst based on whole Ensemble at Horiz Level/Layer + // in a time interval + {12,31,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, + // 4.13: Derived Fcst based on Ensemble cluster over rectangular + // area at Horiz Level/Layer in a time interval + {13,45,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,-4,4,4,1,-1,4,-1,4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, + // 4.14: Derived Fcst based on Ensemble cluster over circular + // area at Horiz Level/Layer in a time interval + {14,44,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,4,4,1,-1,4,-1,4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, + // 4.15: Average, accumulation, extreme values or other statistically-processed values over a + // spatial area at a horizontal level or in a horizontal layer at a point in time + {15,18,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, + // 4.20: Radar Product + {20,19,0, {1,1,1,1,1,-4,4,2,4,2,1,1,1,1,1,2,1,3,2} }, + // 4.30: Satellite Product + {30,5,1, {1,1,1,1,1} }, + // 4.31: Satellite Product + {31,5,1, {1,1,1,1,1} }, + // 4.40: Analysis or forecast at a horizontal level or in a horizontal layer + // at a point in time for atmospheric chemical constituents + {40,16,0, {1,1,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, + // 4.41: Individual ensemble forecast, control and perturbed, at a horizontal level or + // in a horizontal layer at a point in time for atmospheric chemical constituents + {41,19,0, {1,1,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, + // 4.42: Average, accumulation, and/or extreme values or other statistically-processed values + // at a horizontal level or in a horizontal layer in a continuous or non-continuous + // time interval for atmospheric chemical constituents + {42,30,1, {1,1,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, + // 4.43: Individual ensemble forecast, control and perturbed, at a horizontal level + // or in a horizontal layer in a continuous or non-continuous + // time interval for atmospheric chemical constituents + {43,33,1, {1,1,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, + // 4.254: CCITT IA5 Character String + {254,3,0, {1,1,4} }, + // 4.1000: Cross section of analysis or forecast + // at a point in time + {1000,9,0, {1,1,1,1,1,2,1,1,-4} }, + // 4.1001: Cross section of Ave/Accum/etc... analysis or forecast + // in a time interval + {1001,16,0, {1,1,1,1,1,2,1,1,4,4,1,1,1,4,1,4} }, + // 4.1001: Cross section of Ave/Accum/etc... analysis or forecast + // over latitude or longitude + {1002,15,0, {1,1,1,1,1,2,1,1,-4,1,1,1,4,4,2} }, + // 4.1100: Hovmoller-type grid w/ no averaging or other + // statistical processing + {1100,15,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, + // 4.1100: Hovmoller-type grid with averaging or other + // statistical processing + {1101,22,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,4,1,1,1,4,1,4} }, + // 4.32:Simulate (synthetic) Satellite Product + {32,10,1, {1,1,1,1,1,2,1,1,-2,1} }, + // 4.44: Analysis or forecast at a horizontal level or in a horizontal layer + // at a point in time for Aerosol + {44,21,0, {1,1,2,1,-1,-4,-1,-4,1,1,1,2,1,1,-2,1,-1,-4,1,-1,-4} }, + // 4.45: Individual ensemble forecast, control and + // perturbed, at a horizontal level or in a horizontal layer + // at a point in time for Aerosol + {45,24,0, {1,1,2,1,-1,-4,-1,-4,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, + // 4.46: Ave or Accum or Extreme value at level/layer + // at horizontal level or in a horizontal in a continuous or + // non-continuous time interval for Aerosol + {46,35,1, {1,1,2,1,-1,-4,-1,-4,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, + // 4.47: Individual ensemble forecast, control and + // perturbed, at horizontal level or in a horizontal + // in a continuous or non-continuous time interval for Aerosol + {47,38,1, {1,1,1,2,1,-1,-4,-1,-4,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, + + // PDT 4.48 + // 4.48: Analysis or forecast at a horizontal level or in a horizontal layer + // at a point in time for Optical Properties of Aerosol + {48,26,0, {1,1,2,1,-1,-4,-1,-4,1,-1,-4,-1,-4,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, + + // VALIDATION --- PDT 4.50 + // 4.50: Analysis or forecast of multi component parameter or + // matrix element at a point in time + {50,21,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,4,4,4,4} }, + + // VALIDATION --- PDT 4.52 + // 4.52: Analysis or forecast of Wave parameters + // at the Sea surface at a point in time + {52,15,0, {1,1,1,1,1,1,1,1,2,1,1,-4,1,-1,-4} }, + + // 4.51: Categorical forecasts at a horizontal level or + // in a horizontal layer at a point in time + {51,16,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1} }, + + // 4.91: Categorical forecasts at a horizontal level or + // in a horizontal layer at a point in time + // in a continuous or non-continuous time interval + {91,36,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,-1,-4,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, +// PDT 4.33 (07/29/2013) + // 4.33: Individual ensemble forecast, control, perturbed, + // at a horizontal level or in a horizontal layer + // at a point in time for simulated (synthetic) Satellite data + {33,18,1, {1,1,1,1,1,2,1,1,-4,1,2,2,2,-1,-4,1,1,1} }, +// PDT 4.34 (07/29/2013) + // 4.34: Individual ensemble forecast, control, perturbed, + // at a horizontal level or in a horizontal layer,in a continuous or + // non-continuous interval for simulated (synthetic) Satellite data + {34,32,1, {1,1,1,1,1,2,1,1,-4,1,2,2,2,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, +// PDT 4.53 (07/29/2013) + // 4.53: Partitioned parameters at + // horizontal level or horizontal layer + // at a point in time + {53,19,1, {1,1,1,1,4,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, +// PDT 4.54 (07/29/2013) + // 4.54: Individual ensemble forecast, control, perturbed, + // at a horizontal level or in a horizontal layer + // at a point in time for partitioned parameters + {54,22,1, {1,1,1,1,4,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, +// PDT 4.57 (10/07/2015) + // 4.57: Analysis or Forecast at a horizontal or in a + // horizontal layer at a point in time for + // atmospheric chemical constituents based on + // a distribution function + {57,7,1, {1,1,2,2,2,2,1} }, +// PDT 4.60 (10/07/2015) + // 4.60: Individual ensemble reforecast, control and perturbed, + // at a horizontal level or in a horizontal layer + // at a point in time + {60,24,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1} }, +// PDT 4.61 (10/07/2015) + // 4.61: Individual ensemble reforecast, control and perturbed, + // at a horizontal level or in a horizontal layer + // in a continuous or non-continuous time interval + {61,38,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, +// VALIDATION --- PDT 4.35 +// PDT 4.35 (10/07/2015) + // 4.35: Individual ensemble reforecast, control and perturbed, + // at a horizontal level or in a horizontal layer + // in a continuous or non-continuous time interval + {35,6,1, {1,1,1,1,1,1} } + +} ; + + g2int getpdsindex(g2int number) ///$$$ SUBPROGRAM DOCUMENTATION BLOCK // . . . . diff -up g2clib-1.6.0.p1/pdstemplates.h g2clib-1.6.0.p12/pdstemplates.h --- g2clib-1.6.0.p1/pdstemplates.h 2017-08-13 10:17:37.483288583 +0200 +++ g2clib-1.6.0.p12/pdstemplates.h 2017-08-13 10:36:42.046773771 +0200 @@ -54,176 +54,8 @@ g2int mappds[MAXPDSMAPLEN]; }; - const struct pdstemplate templatespds[MAXPDSTEMP] = { - // 4.0: Analysis or Forecast at Horizontal Level/Layer - // at a point in time - {0,15,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, - // 4.1: Individual Ensemble Forecast at Horizontal Level/Layer - // at a point in time - {1,18,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, - // 4.2: Derived Fcst based on whole Ensemble at Horiz Level/Layer - // at a point in time - {2,17,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1} }, - // 4.3: Derived Fcst based on Ensemble cluster over rectangular - // area at Horiz Level/Layer at a point in time - {3,31,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,-4,4,4,1,-1,4,-1,4} }, - // 4.4: Derived Fcst based on Ensemble cluster over circular - // area at Horiz Level/Layer at a point in time - {4,30,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,4,4,1,-1,4,-1,4} }, - // 4.5: Probablility Forecast at Horiz Level/Layer - // at a point in time - {5,22,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,-1,-4,-1,-4} }, - // 4.6: Percentile Forecast at Horiz Level/Layer - // at a point in time - {6,16,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1} }, - // 4.7: Analysis or Forecast Error at Horizontal Level/Layer - // at a point in time - {7,15,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, - // 4.8: Ave/Accum/etc... at Horiz Level/Layer - // in a time interval - {8,29,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, - // 4.9: Probablility Forecast at Horiz Level/Layer - // in a time interval - {9,36,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,-1,-4,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, - // 4.10: Percentile Forecast at Horiz Level/Layer - // in a time interval - {10,30,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, - // 4.11: Individual Ensemble Forecast at Horizontal Level/Layer - // in a time interval - {11,32,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, - // 4.12: Derived Fcst based on whole Ensemble at Horiz Level/Layer - // in a time interval - {12,31,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, - // 4.13: Derived Fcst based on Ensemble cluster over rectangular - // area at Horiz Level/Layer in a time interval - {13,45,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,-4,4,4,1,-1,4,-1,4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, - // 4.14: Derived Fcst based on Ensemble cluster over circular - // area at Horiz Level/Layer in a time interval - {14,44,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,1,1,1,1,-4,4,4,1,-1,4,-1,4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, - // 4.15: Average, accumulation, extreme values or other statistically-processed values over a - // spatial area at a horizontal level or in a horizontal layer at a point in time - {15,18,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, - // 4.20: Radar Product - {20,19,0, {1,1,1,1,1,-4,4,2,4,2,1,1,1,1,1,2,1,3,2} }, - // 4.30: Satellite Product - {30,5,1, {1,1,1,1,1} }, - // 4.31: Satellite Product - {31,5,1, {1,1,1,1,1} }, - // 4.40: Analysis or forecast at a horizontal level or in a horizontal layer - // at a point in time for atmospheric chemical constituents - {40,16,0, {1,1,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, - // 4.41: Individual ensemble forecast, control and perturbed, at a horizontal level or - // in a horizontal layer at a point in time for atmospheric chemical constituents - {41,19,0, {1,1,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, - // 4.42: Average, accumulation, and/or extreme values or other statistically-processed values - // at a horizontal level or in a horizontal layer in a continuous or non-continuous - // time interval for atmospheric chemical constituents - {42,30,1, {1,1,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, - // 4.43: Individual ensemble forecast, control and perturbed, at a horizontal level - // or in a horizontal layer in a continuous or non-continuous - // time interval for atmospheric chemical constituents - {43,33,1, {1,1,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, - // 4.254: CCITT IA5 Character String - {254,3,0, {1,1,4} }, - // 4.1000: Cross section of analysis or forecast - // at a point in time - {1000,9,0, {1,1,1,1,1,2,1,1,-4} }, - // 4.1001: Cross section of Ave/Accum/etc... analysis or forecast - // in a time interval - {1001,16,0, {1,1,1,1,1,2,1,1,4,4,1,1,1,4,1,4} }, - // 4.1001: Cross section of Ave/Accum/etc... analysis or forecast - // over latitude or longitude - {1002,15,0, {1,1,1,1,1,2,1,1,-4,1,1,1,4,4,2} }, - // 4.1100: Hovmoller-type grid w/ no averaging or other - // statistical processing - {1100,15,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, - // 4.1100: Hovmoller-type grid with averaging or other - // statistical processing - {1101,22,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,4,1,1,1,4,1,4} }, - // 4.32:Simulate (synthetic) Satellite Product - {32,10,1, {1,1,1,1,1,2,1,1,-2,1} }, - // 4.44: Analysis or forecast at a horizontal level or in a horizontal layer - // at a point in time for Aerosol - {44,21,0, {1,1,2,1,-1,-4,-1,-4,1,1,1,2,1,1,-2,1,-1,-4,1,-1,-4} }, - // 4.45: Individual ensemble forecast, control and - // perturbed, at a horizontal level or in a horizontal layer - // at a point in time for Aerosol - {45,24,0, {1,1,2,1,-1,-4,-1,-4,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, - // 4.46: Ave or Accum or Extreme value at level/layer - // at horizontal level or in a horizontal in a continuous or - // non-continuous time interval for Aerosol - {46,35,1, {1,1,2,1,-1,-4,-1,-4,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, - // 4.47: Individual ensemble forecast, control and - // perturbed, at horizontal level or in a horizontal - // in a continuous or non-continuous time interval for Aerosol - {47,38,1, {1,1,1,2,1,-1,-4,-1,-4,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, - - // PDT 4.48 - // 4.48: Analysis or forecast at a horizontal level or in a horizontal layer - // at a point in time for Optical Properties of Aerosol - {48,26,0, {1,1,2,1,-1,-4,-1,-4,1,-1,-4,-1,-4,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, - - // VALIDATION --- PDT 4.50 - // 4.50: Analysis or forecast of multi component parameter or - // matrix element at a point in time - {50,21,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,4,4,4,4} }, - - // VALIDATION --- PDT 4.52 - // 4.52: Analysis or forecast of Wave parameters - // at the Sea surface at a point in time - {52,15,0, {1,1,1,1,1,1,1,1,2,1,1,-4,1,-1,-4} }, - - // 4.51: Categorical forecasts at a horizontal level or - // in a horizontal layer at a point in time - {51,16,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1} }, - - // 4.91: Categorical forecasts at a horizontal level or - // in a horizontal layer at a point in time - // in a continuous or non-continuous time interval - {91,36,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,-1,-4,-1,-4,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, -// PDT 4.33 (07/29/2013) - // 4.33: Individual ensemble forecast, control, perturbed, - // at a horizontal level or in a horizontal layer - // at a point in time for simulated (synthetic) Satellite data - {33,18,1, {1,1,1,1,1,2,1,1,-4,1,2,2,2,-1,-4,1,1,1} }, -// PDT 4.34 (07/29/2013) - // 4.34: Individual ensemble forecast, control, perturbed, - // at a horizontal level or in a horizontal layer,in a continuous or - // non-continuous interval for simulated (synthetic) Satellite data - {34,32,1, {1,1,1,1,1,2,1,1,-4,1,2,2,2,-1,-4,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, -// PDT 4.53 (07/29/2013) - // 4.53: Partitioned parameters at - // horizontal level or horizontal layer - // at a point in time - {53,19,1, {1,1,1,1,4,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4} }, -// PDT 4.54 (07/29/2013) - // 4.54: Individual ensemble forecast, control, perturbed, - // at a horizontal level or in a horizontal layer - // at a point in time for partitioned parameters - {54,22,1, {1,1,1,1,4,2,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1} }, -// PDT 4.57 (10/07/2015) - // 4.57: Analysis or Forecast at a horizontal or in a - // horizontal layer at a point in time for - // atmospheric chemical constituents based on - // a distribution function - {57,7,1, {1,1,2,2,2,2,1} }, -// PDT 4.60 (10/07/2015) - // 4.60: Individual ensemble reforecast, control and perturbed, - // at a horizontal level or in a horizontal layer - // at a point in time - {60,24,0, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1} }, -// PDT 4.61 (10/07/2015) - // 4.61: Individual ensemble reforecast, control and perturbed, - // at a horizontal level or in a horizontal layer - // in a continuous or non-continuous time interval - {61,38,1, {1,1,1,1,1,2,1,1,-4,1,-1,-4,1,-1,-4,1,1,1,2,1,1,1,1,1,2,1,1,1,1,1,1,4,1,1,1,4,1,4} }, -// VALIDATION --- PDT 4.35 -// PDT 4.35 (10/07/2015) - // 4.35: Individual ensemble reforecast, control and perturbed, - // at a horizontal level or in a horizontal layer - // in a continuous or non-continuous time interval - {35,6,1, {1,1,1,1,1,1} } - - } ; + extern const struct pdstemplate templatespds[]; + + g2int getpdsindex(g2int number); #endif /* _pdstemplates_H */ 07070100000009000081A400000000000000000000000163B39B3400000CA8000000000000000000000000000000000000002600000000g2clib-1672715060.88a25f7/g2clib.spec%global macrosdir %(d=%{_rpmconfigdir}/macros.d; [ -d $d ] || d=%{_sysconfdir}/rpm; echo $d) Name: g2clib Version: 1.6.0 Release: 1 Summary: GRIB2 encoder/decoder and search/indexing routines in C License: Public Domain URL: http://www.nco.ncep.noaa.gov/pmb/codes/GRIB2/ Source0: http://www.nco.ncep.noaa.gov/pmb/codes/GRIB2/g2clib-%{version}.tar Source1: g2clib-msg.txt #Patch to fix up type detection and printf arguments on 64-bit machines Patch0: g2clib-64bit.patch # Patch to remove multiple definitions of templates Patch1: g2clib-templates.patch # Patch from Wesley Ebisuzaki <wesley.ebisuzaki@noaa.gov> to fix sigfault # if simunpack() is called with 0 values to unpack Patch2: g2clib-simunpack.patch # Patch from degrib - appears to fix projection issues Patch3: g2clib-degrib.patch # Fix build with Jasper 2 Patch4: g2clib-jasper2.patch BuildRequires: gcc BuildRequires: libpng-devel jasper-devel # static only library - no debuginfo %global debug_package %{nil} %if %{lua: print(rpm.vercmp(rpm.expand("%version"),"1.6.0"))} >= 0 %global g2clib g2c_v%{version} %else %global g2clib grib2c %endif %description This library contains "C" decoder/encoder routines for GRIB edition 2. The user API for the GRIB2 routines is described in ASCII file "grib2c.doc". %package devel Summary: Development files for %{name} #Requires: %%{name} = %%{version}-%%{release} Provides: %{name}-static = %{version}-%{release} Requires: libpng-devel jasper-devel %description devel This library contains "C" decoder/encoder routines for GRIB edition 2. The user API for the GRIB2 routines is described in file "grib2c.doc". The %{name}-devel package contains libraries and header files for developing applications that use %{name}. %prep %setup -q %patch0 -p1 -b .64bit %patch1 -p1 -b .templates %patch2 -p1 -b .simunpack %patch3 -p1 -b .degrib %patch4 -p1 -b .jasper2 chmod a-x *.h *.c README CHANGES grib2c.doc makefile cp -p %{SOURCE1} . %build CFLAGS="$RPM_OPT_FLAGS -DUSE_PNG -DUSE_JPEG2000" %ifarch sparc64 s390x %{mips64} CFLAGS="$CFLAGS -D__64BIT__ -fPIC" %endif %ifarch x86_64 ia64 %{power64} aarch64 CFLAGS="$CFLAGS -D__64BIT__ -fpic" %endif %ifarch %{ix86} %{arm} %{mips32} CFLAGS="$CFLAGS -fpic" %endif make CFLAGS="$CFLAGS" CC="%{__cc}" ARFLAGS= %install mkdir -p $RPM_BUILD_ROOT%{_libdir} $RPM_BUILD_ROOT%{_includedir} install -p -m0644 lib%{g2clib}.a $RPM_BUILD_ROOT%{_libdir} install -p -m0644 grib2.h $RPM_BUILD_ROOT%{_includedir} install -p -m0644 drstemplates.h $RPM_BUILD_ROOT%{_includedir} install -p -m0644 gridtemplates.h $RPM_BUILD_ROOT%{_includedir} install -p -m0644 pdstemplates.h $RPM_BUILD_ROOT%{_includedir} mkdir -p $RPM_BUILD_ROOT%{macrosdir} echo %%g2clib %g2clib > $RPM_BUILD_ROOT%{macrosdir}/macros.g2clib %files devel %doc README CHANGES grib2c.doc g2clib-msg.txt #%%{_libdir}/libgrib2c.a %{_libdir}/lib%{g2clib}.a %{_includedir}/grib2.h %{_includedir}/drstemplates.h %{_includedir}/gridtemplates.h %{_includedir}/pdstemplates.h %{macrosdir}/macros.g2clib %changelog * Web Feb 03 2021 yangshaoxing <yangshaoxing@uniontech.com> - 1.6.0-1 - Package init 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!997 blocks
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2