LCOV - code coverage report
Current view: directory - frmts/grib/degrib18/g2clib-1.0.4 - compack.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 206 0 0.0 %
Date: 2010-01-09 Functions: 1 0 0.0 %

       1                 : #include <stdlib.h>
       2                 : #include <math.h>
       3                 : #include "grib2.h"
       4                 : 
       5                 : 
       6               0 : void compack(g2float *fld,g2int ndpts,g2int idrsnum,g2int *idrstmpl,
       7                 :              unsigned char *cpack,g2int *lcpack)
       8                 : //$$$  SUBPROGRAM DOCUMENTATION BLOCK
       9                 : //                .      .    .                                       .
      10                 : // SUBPROGRAM:    compack
      11                 : //   PRGMMR: Gilbert          ORG: W/NP11    DATE: 2002-11-07
      12                 : //
      13                 : // ABSTRACT: This subroutine packs up a data field using a complex
      14                 : //   packing algorithm as defined in the GRIB2 documention.  It
      15                 : //   supports GRIB2 complex packing templates with or without
      16                 : //   spatial differences (i.e. DRTs 5.2 and 5.3).
      17                 : //   It also fills in GRIB2 Data Representation Template 5.2 or 5.3 
      18                 : //   with the appropriate values.
      19                 : //
      20                 : // PROGRAM HISTORY LOG:
      21                 : // 2002-11-07  Gilbert
      22                 : //
      23                 : // USAGE:    void compack(g2float *fld,g2int ndpts,g2int idrsnum,
      24                 : //                g2int *idrstmpl,unsigned char *cpack,g2int *lcpack)
      25                 : //
      26                 : //   INPUT ARGUMENTS:
      27                 : //     fld[]    - Contains the data values to pack
      28                 : //     ndpts    - The number of data values in array fld[]
      29                 : //     idrsnum  - Data Representation Template number 5.N
      30                 : //                Must equal 2 or 3.
      31                 : //     idrstmpl - Contains the array of values for Data Representation
      32                 : //                Template 5.2 or 5.3
      33                 : //                [0] = Reference value - ignored on input
      34                 : //                [1] = Binary Scale Factor
      35                 : //                [2] = Decimal Scale Factor
      36                 : //                    .
      37                 : //                    .
      38                 : //                [6] = Missing value management
      39                 : //                [7] = Primary missing value
      40                 : //                [8] = Secondary missing value
      41                 : //                    .
      42                 : //                    .
      43                 : //               [16] = Order of Spatial Differencing  ( 1 or 2 )
      44                 : //                    .
      45                 : //                    .
      46                 : //
      47                 : //   OUTPUT ARGUMENTS: 
      48                 : //     idrstmpl - Contains the array of values for Data Representation
      49                 : //                Template 5.3
      50                 : //                [0] = Reference value - set by compack routine.
      51                 : //                [1] = Binary Scale Factor - unchanged from input
      52                 : //                [2] = Decimal Scale Factor - unchanged from input
      53                 : //                    .
      54                 : //                    .
      55                 : //     cpack    - The packed data field
      56                 : //     lcpack   - length of packed field cpack.
      57                 : //
      58                 : // REMARKS: None
      59                 : //
      60                 : // ATTRIBUTES:
      61                 : //   LANGUAGE: C
      62                 : //   MACHINE:
      63                 : //
      64                 : //$$$
      65                 : {
      66                 : 
      67                 :       static g2int zero=0;
      68                 :       g2int  *ifld,*gref,*glen,*gwidth;
      69                 :       g2int  *jmin, *jmax, *lbit;
      70                 :       g2int  i,j,n,nbits,imin,imax,left;
      71               0 :       g2int  isd,itemp,ilmax,ngwidthref=0,nbitsgwidth=0;
      72               0 :       g2int  nglenref=0,nglenlast=0,iofst,ival1,ival2;
      73               0 :       g2int  minsd,nbitsd=0,maxorig,nbitorig,ngroups;
      74                 :       g2int  lg,ng,igmax,iwmax,nbitsgref;
      75               0 :       g2int  glength,grpwidth,nbitsglen=0;
      76                 :       g2int  kfildo, minpk, inc, maxgrps, ibit, jbit, kbit, novref, lbitref;
      77                 :       g2int  missopt, miss1, miss2, ier;
      78                 :       g2float  bscale,dscale,rmax,rmin,temp;
      79                 :       static g2int simple_alg = 0;
      80                 :       static g2float alog2=0.69314718;       //  ln(2.0)
      81                 :       static g2int one=1;
      82                 : 
      83               0 :       bscale=int_power(2.0,-idrstmpl[1]);
      84               0 :       dscale=int_power(10.0,idrstmpl[2]);
      85                 : //
      86                 : //  Find max and min values in the data
      87                 : //
      88               0 :       rmax=fld[0];
      89               0 :       rmin=fld[0];
      90               0 :       for (j=1;j<ndpts;j++) {
      91               0 :         if (fld[j] > rmax) rmax=fld[j];
      92               0 :         if (fld[j] < rmin) rmin=fld[j];
      93                 :       }
      94                 : 
      95                 : //
      96                 : //  If max and min values are not equal, pack up field.
      97                 : //  If they are equal, we have a constant field, and the reference
      98                 : //  value (rmin) is the value for each point in the field and
      99                 : //  set nbits to 0.
     100                 : //
     101               0 :       if (rmin != rmax) {
     102               0 :         iofst=0;
     103               0 :         ifld=calloc(ndpts,sizeof(g2int));
     104               0 :         gref=calloc(ndpts,sizeof(g2int));
     105               0 :         gwidth=calloc(ndpts,sizeof(g2int));
     106               0 :         glen=calloc(ndpts,sizeof(g2int));
     107                 :         //
     108                 :         //  Scale original data
     109                 :         //
     110               0 :         if (idrstmpl[1] == 0) {        //  No binary scaling
     111               0 :            imin=(g2int)RINT(rmin*dscale);
     112                 :            //imax=(g2int)rint(rmax*dscale);
     113               0 :            rmin=(g2float)imin;
     114               0 :            for (j=0;j<ndpts;j++) 
     115               0 :               ifld[j]=(g2int)RINT(fld[j]*dscale)-imin;
     116                 :         }
     117                 :         else {                             //  Use binary scaling factor
     118               0 :            rmin=rmin*dscale;
     119                 :            //rmax=rmax*dscale;
     120               0 :            for (j=0;j<ndpts;j++) 
     121               0 :              ifld[j]=(g2int)RINT(((fld[j]*dscale)-rmin)*bscale);
     122                 :         }
     123                 :         //
     124                 :         //  Calculate Spatial differences, if using DRS Template 5.3
     125                 :         //
     126               0 :         if (idrsnum == 3) {        // spatial differences
     127               0 :            if (idrstmpl[16]!=1 && idrstmpl[16]!=2) idrstmpl[16]=1;
     128               0 :            if (idrstmpl[16] == 1) {      // first order
     129               0 :               ival1=ifld[0];
     130               0 :               for (j=ndpts-1;j>0;j--) 
     131               0 :                  ifld[j]=ifld[j]-ifld[j-1];
     132               0 :               ifld[0]=0;
     133                 :            }
     134               0 :            else if (idrstmpl[16] == 2) {      // second order
     135               0 :               ival1=ifld[0];
     136               0 :               ival2=ifld[1];
     137               0 :               for (j=ndpts-1;j>1;j--) 
     138               0 :                  ifld[j]=ifld[j]-(2*ifld[j-1])+ifld[j-2];
     139               0 :               ifld[0]=0;
     140               0 :               ifld[1]=0;
     141                 :            }
     142                 :            //
     143                 :            //  subtract min value from spatial diff field
     144                 :            //
     145               0 :            isd=idrstmpl[16];
     146               0 :            minsd=ifld[isd];
     147               0 :            for (j=isd;j<ndpts;j++)  if ( ifld[j] < minsd ) minsd=ifld[j];
     148               0 :            for (j=isd;j<ndpts;j++)  ifld[j]=ifld[j]-minsd;
     149                 :            //
     150                 :            //   find num of bits need to store minsd and add 1 extra bit
     151                 :            //   to indicate sign
     152                 :            //
     153               0 :            temp=log((double)(abs(minsd)+1))/alog2;
     154               0 :            nbitsd=(g2int)ceil(temp)+1;
     155                 :            //
     156                 :            //   find num of bits need to store ifld[0] ( and ifld[1]
     157                 :            //   if using 2nd order differencing )
     158                 :            //
     159               0 :            maxorig=ival1;
     160               0 :            if (idrstmpl[16]==2 && ival2>ival1) maxorig=ival2;
     161               0 :            temp=log((double)(maxorig+1))/alog2;
     162               0 :            nbitorig=(g2int)ceil(temp)+1;
     163               0 :            if (nbitorig > nbitsd) nbitsd=nbitorig;
     164                 :            //   increase number of bits to even multiple of 8 ( octet )
     165               0 :            if ( (nbitsd%8) != 0) nbitsd=nbitsd+(8-(nbitsd%8));
     166                 :            //
     167                 :            //  Store extra spatial differencing info into the packed
     168                 :            //  data section.
     169                 :            //
     170               0 :            if (nbitsd != 0) {
     171                 :               //   pack first original value
     172               0 :               if (ival1 >= 0) {
     173               0 :                  sbit(cpack,&ival1,iofst,nbitsd);
     174               0 :                  iofst=iofst+nbitsd;
     175                 :               }
     176                 :               else {
     177               0 :                  sbit(cpack,&one,iofst,1);
     178               0 :                  iofst=iofst+1;
     179               0 :                  itemp=abs(ival1);
     180               0 :                  sbit(cpack,&itemp,iofst,nbitsd-1);
     181               0 :                  iofst=iofst+nbitsd-1;
     182                 :               }
     183               0 :               if (idrstmpl[16] == 2) {
     184                 :                //  pack second original value
     185               0 :                  if (ival2 >= 0) {
     186               0 :                     sbit(cpack,&ival2,iofst,nbitsd);
     187               0 :                     iofst=iofst+nbitsd;
     188                 :                  }
     189                 :                  else {
     190               0 :                     sbit(cpack,&one,iofst,1);
     191               0 :                     iofst=iofst+1;
     192               0 :                     itemp=abs(ival2);
     193               0 :                     sbit(cpack,&itemp,iofst,nbitsd-1);
     194               0 :                     iofst=iofst+nbitsd-1;
     195                 :                  }
     196                 :               }
     197                 :               //  pack overall min of spatial differences
     198               0 :               if (minsd >= 0) {
     199               0 :                  sbit(cpack,&minsd,iofst,nbitsd);
     200               0 :                  iofst=iofst+nbitsd;
     201                 :               }
     202                 :               else {
     203               0 :                  sbit(cpack,&one,iofst,1);
     204               0 :                  iofst=iofst+1;
     205               0 :                  itemp=abs(minsd);
     206               0 :                  sbit(cpack,&itemp,iofst,nbitsd-1);
     207               0 :                  iofst=iofst+nbitsd-1;
     208                 :               }
     209                 :            }
     210                 :            //printf("SDp %ld %ld %ld %ld\n",ival1,ival2,minsd,nbitsd);
     211                 :         }     //  end of spatial diff section
     212                 :         //
     213                 :         //   Determine Groups to be used.
     214                 :         //
     215               0 :         if ( simple_alg == 1 ) {
     216                 :            //  set group length to 10;  calculate number of groups
     217                 :            //  and length of last group
     218               0 :            ngroups=ndpts/10;
     219               0 :            for (j=0;j<ngroups;j++) glen[j]=10;
     220               0 :            itemp=ndpts%10;
     221               0 :            if (itemp != 0) {
     222               0 :               ngroups=ngroups+1;
     223               0 :               glen[ngroups-1]=itemp;
     224                 :            }
     225                 :         }
     226                 :         else {
     227                 :            // Use Dr. Glahn's algorithm for determining grouping.
     228                 :            //
     229               0 :            kfildo=6;
     230               0 :            minpk=10;
     231               0 :            inc=1;
     232               0 :            maxgrps=(ndpts/minpk)+1;
     233               0 :            jmin = calloc(maxgrps,sizeof(g2int));
     234               0 :            jmax = calloc(maxgrps,sizeof(g2int));
     235               0 :            lbit = calloc(maxgrps,sizeof(g2int));
     236               0 :            missopt=0;
     237               0 :            pack_gp(&kfildo,ifld,&ndpts,&missopt,&minpk,&inc,&miss1,&miss2,
     238                 :                         jmin,jmax,lbit,glen,&maxgrps,&ngroups,&ibit,&jbit,
     239                 :                         &kbit,&novref,&lbitref,&ier);
     240                 :            //print *,'SAGier = ',ier,ibit,jbit,kbit,novref,lbitref
     241               0 :            for ( ng=0; ng<ngroups; ng++) glen[ng]=glen[ng]+novref;
     242               0 :            free(jmin);
     243               0 :            free(jmax);
     244               0 :            free(lbit);
     245                 :         }
     246                 :         //  
     247                 :         //  For each group, find the group's reference value
     248                 :         //  and the number of bits needed to hold the remaining values
     249                 :         //
     250               0 :         n=0;
     251               0 :         for (ng=0;ng<ngroups;ng++) {
     252                 :            //    find max and min values of group
     253               0 :            gref[ng]=ifld[n];
     254               0 :            imax=ifld[n];
     255               0 :            j=n+1;
     256               0 :            for (lg=1;lg<glen[ng];lg++) {
     257               0 :               if (ifld[j] < gref[ng]) gref[ng]=ifld[j]; 
     258               0 :               if (ifld[j] > imax) imax=ifld[j];
     259               0 :               j++;
     260                 :            }
     261                 :            //   calc num of bits needed to hold data
     262               0 :            if ( gref[ng] != imax ) {
     263               0 :               temp=log((double)(imax-gref[ng]+1))/alog2;
     264               0 :               gwidth[ng]=(g2int)ceil(temp);
     265                 :            }
     266                 :            else 
     267               0 :               gwidth[ng]=0;
     268                 :            //   Subtract min from data
     269               0 :            j=n;
     270               0 :            for (lg=0;lg<glen[ng];lg++) {
     271               0 :               ifld[j]=ifld[j]-gref[ng];
     272               0 :               j++;
     273                 :            }
     274                 :            //   increment fld array counter
     275               0 :            n=n+glen[ng];
     276                 :         }
     277                 :         //  
     278                 :         //  Find max of the group references and calc num of bits needed 
     279                 :         //  to pack each groups reference value, then
     280                 :         //  pack up group reference values
     281                 :         //
     282               0 :         igmax=gref[0];
     283               0 :         for (j=1;j<ngroups;j++) if (gref[j] > igmax) igmax=gref[j];
     284               0 :         if (igmax != 0) {
     285               0 :            temp=log((double)(igmax+1))/alog2;
     286               0 :            nbitsgref=(g2int)ceil(temp);
     287               0 :            sbits(cpack,gref,iofst,nbitsgref,0,ngroups);
     288               0 :            itemp=nbitsgref*ngroups;
     289               0 :            iofst=iofst+itemp;
     290                 :            //         Pad last octet with Zeros, if necessary,
     291               0 :            if ( (itemp%8) != 0) {
     292               0 :               left=8-(itemp%8);
     293               0 :               sbit(cpack,&zero,iofst,left);
     294               0 :               iofst=iofst+left;
     295                 :            }
     296                 :         }
     297                 :         else
     298               0 :            nbitsgref=0;
     299                 :         //
     300                 :         //  Find max/min of the group widths and calc num of bits needed
     301                 :         //  to pack each groups width value, then
     302                 :         //  pack up group width values
     303                 :         //
     304               0 :         iwmax=gwidth[0];
     305               0 :         ngwidthref=gwidth[0];
     306               0 :         for (j=1;j<ngroups;j++) {
     307               0 :            if (gwidth[j] > iwmax) iwmax=gwidth[j];
     308               0 :            if (gwidth[j] < ngwidthref) ngwidthref=gwidth[j];
     309                 :         }
     310               0 :         if (iwmax != ngwidthref) {
     311               0 :            temp=log((double)(iwmax-ngwidthref+1))/alog2;
     312               0 :            nbitsgwidth=(g2int)ceil(temp);
     313               0 :            for (i=0;i<ngroups;i++) 
     314               0 :               gwidth[i]=gwidth[i]-ngwidthref;
     315               0 :            sbits(cpack,gwidth,iofst,nbitsgwidth,0,ngroups);
     316               0 :            itemp=nbitsgwidth*ngroups;
     317               0 :            iofst=iofst+itemp;
     318                 :            //         Pad last octet with Zeros, if necessary,
     319               0 :            if ( (itemp%8) != 0) {
     320               0 :               left=8-(itemp%8);
     321               0 :               sbit(cpack,&zero,iofst,left);
     322               0 :               iofst=iofst+left;
     323                 :            }
     324                 :         }
     325                 :         else {
     326               0 :            nbitsgwidth=0;
     327               0 :            for (i=0;i<ngroups;i++) gwidth[i]=0;
     328                 :         }
     329                 :         //
     330                 :         //  Find max/min of the group lengths and calc num of bits needed
     331                 :         //  to pack each groups length value, then
     332                 :         //  pack up group length values
     333                 :         //
     334                 :         //write(77,*)'GLENS: ',(glen(j),j=1,ngroups)
     335               0 :         ilmax=glen[0];
     336               0 :         nglenref=glen[0];
     337               0 :         for (j=1;j<ngroups-1;j++) {
     338               0 :            if (glen[j] > ilmax) ilmax=glen[j];
     339               0 :            if (glen[j] < nglenref) nglenref=glen[j];
     340                 :         }
     341               0 :         nglenlast=glen[ngroups-1];
     342               0 :         if (ilmax != nglenref) {
     343               0 :            temp=log((double)(ilmax-nglenref+1))/alog2;
     344               0 :            nbitsglen=(g2int)ceil(temp);
     345               0 :            for (i=0;i<ngroups-1;i++)  glen[i]=glen[i]-nglenref;
     346               0 :            sbits(cpack,glen,iofst,nbitsglen,0,ngroups);
     347               0 :            itemp=nbitsglen*ngroups;
     348               0 :            iofst=iofst+itemp;
     349                 :            //         Pad last octet with Zeros, if necessary,
     350               0 :            if ( (itemp%8) != 0) {
     351               0 :               left=8-(itemp%8);
     352               0 :               sbit(cpack,&zero,iofst,left);
     353               0 :               iofst=iofst+left;
     354                 :            }
     355                 :         }
     356                 :         else {
     357               0 :            nbitsglen=0;
     358               0 :            for (i=0;i<ngroups;i++) glen[i]=0;
     359                 :         }
     360                 :         //
     361                 :         //  For each group, pack data values
     362                 :         //
     363               0 :         n=0;
     364               0 :         for (ng=0;ng<ngroups;ng++) {
     365               0 :            glength=glen[ng]+nglenref;
     366               0 :            if (ng == (ngroups-1) ) glength=nglenlast;
     367               0 :            grpwidth=gwidth[ng]+ngwidthref;
     368               0 :            if ( grpwidth != 0 ) {
     369               0 :               sbits(cpack,ifld+n,iofst,grpwidth,0,glength);
     370               0 :               iofst=iofst+(grpwidth*glength);
     371                 :            }
     372               0 :            n=n+glength;
     373                 :         }
     374                 :         //         Pad last octet with Zeros, if necessary,
     375               0 :         if ( (iofst%8) != 0) {
     376               0 :            left=8-(iofst%8);
     377               0 :            sbit(cpack,&zero,iofst,left);
     378               0 :            iofst=iofst+left;
     379                 :         }
     380               0 :         *lcpack=iofst/8;
     381                 :         //
     382               0 :         if ( ifld!=0 ) free(ifld);
     383               0 :         if ( gref!=0 ) free(gref);
     384               0 :         if ( gwidth!=0 ) free(gwidth);
     385               0 :         if ( glen!=0 ) free(glen);
     386                 :       }
     387                 :       else {          //   Constant field ( max = min )
     388               0 :         nbits=0;
     389               0 :         *lcpack=0;
     390               0 :         nbitsgref=0;
     391               0 :         ngroups=0;
     392                 :       }
     393                 : 
     394                 : //
     395                 : //  Fill in ref value and number of bits in Template 5.2
     396                 : //
     397               0 :       mkieee(&rmin,idrstmpl+0,1);   // ensure reference value is IEEE format
     398               0 :       idrstmpl[3]=nbitsgref;
     399               0 :       idrstmpl[4]=0;         // original data were reals
     400               0 :       idrstmpl[5]=1;         // general group splitting
     401               0 :       idrstmpl[6]=0;         // No internal missing values
     402               0 :       idrstmpl[7]=0;         // Primary missing value
     403               0 :       idrstmpl[8]=0;         // secondary missing value
     404               0 :       idrstmpl[9]=ngroups;          // Number of groups
     405               0 :       idrstmpl[10]=ngwidthref;       // reference for group widths
     406               0 :       idrstmpl[11]=nbitsgwidth;      // num bits used for group widths
     407               0 :       idrstmpl[12]=nglenref;         // Reference for group lengths
     408               0 :       idrstmpl[13]=1;                // length increment for group lengths
     409               0 :       idrstmpl[14]=nglenlast;        // True length of last group
     410               0 :       idrstmpl[15]=nbitsglen;        // num bits used for group lengths
     411               0 :       if (idrsnum == 3) {
     412               0 :          idrstmpl[17]=nbitsd/8;      // num bits used for extra spatial
     413                 :                                      // differencing values
     414                 :       }
     415                 : 
     416               0 : }

Generated by: LCOV version 1.7