#include #include #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; j0; 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; jival1) 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 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 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 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 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