LCOV - code coverage report
Current view: top level - frmts/grib/degrib/g2clib - simpack.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 64 87 73.6 %
Date: 2024-05-06 18:28:20 Functions: 1 1 100.0 %

          Line data    Source code
       1             : #include <stdlib.h>
       2             : #include <math.h>
       3             : #include <limits.h>
       4             : #include <float.h>
       5             : #include "grib2.h"
       6             : 
       7             : 
       8          65 : void simpack(g2float *fld,g2int ndpts,g2int *idrstmpl,unsigned char *cpack,g2int *lcpack)
       9             : //$$$  SUBPROGRAM DOCUMENTATION BLOCK
      10             : //                .      .    .                                       .
      11             : // SUBPROGRAM:    simpack
      12             : //   PRGMMR: Gilbert          ORG: W/NP11    DATE: 2002-11-06
      13             : //
      14             : // ABSTRACT: This subroutine packs up a data field using the simple
      15             : //   packing algorithm as defined in the GRIB2 documentation.  It
      16             : //   also fills in GRIB2 Data Representation Template 5.0 with the
      17             : //   appropriate values.
      18             : //
      19             : // PROGRAM HISTORY LOG:
      20             : // 2002-11-06  Gilbert
      21             : //
      22             : // USAGE:    CALL simpack(fld,ndpts,idrstmpl,cpack,lcpack)
      23             : //   INPUT ARGUMENT LIST:
      24             : //     fld[]    - Contains the data values to pack
      25             : //     ndpts    - The number of data values in array fld[]
      26             : //     idrstmpl - Contains the array of values for Data Representation
      27             : //                Template 5.0
      28             : //                [0] = Reference value - ignored on input
      29             : //                [1] = Binary Scale Factor
      30             : //                [2] = Decimal Scale Factor
      31             : //                [3] = Number of bits used to pack data, if value is
      32             : //                      > 0 and  <= 31.
      33             : //                      If this input value is 0 or outside above range
      34             : //                      then the num of bits is calculated based on given
      35             : //                      data and scale factors.
      36             : //                [4] = Original field type - currently ignored on input
      37             : //                      Data values assumed to be reals.
      38             : //
      39             : //   OUTPUT ARGUMENT LIST:
      40             : //     idrstmpl - Contains the array of values for Data Representation
      41             : //                Template 5.0
      42             : //                [0] = Reference value - set by simpack routine.
      43             : //                [1] = Binary Scale Factor - unchanged from input
      44             : //                [2] = Decimal Scale Factor - unchanged from input
      45             : //                [3] = Number of bits used to pack data, unchanged from
      46             : //                      input if value is between 0 and 31.
      47             : //                      If this input value is 0 or outside above range
      48             : //                      then the num of bits is calculated based on given
      49             : //                      data and scale factors.
      50             : //                [4] = Original field type - currently set = 0 on output.
      51             : //                      Data values assumed to be reals.
      52             : //     cpack    - The packed data field
      53             : //     lcpack   - length of packed field starting at cpack.
      54             : //
      55             : // REMARKS: None
      56             : //
      57             : // ATTRIBUTES:
      58             : //   LANGUAGE: C
      59             : //   MACHINE:
      60             : //
      61             : //$$$
      62             : {
      63             : 
      64          65 :       const g2int zero=0;
      65             :       g2int  *ifld;
      66             :       g2int  j,nbits,maxdif,nbittot,left;
      67             :       g2float  bscale,dscale,rmax,rmin,temp, ref, rmin_dscaled, rmax_dscaled;
      68             :       double maxnum;
      69          65 :       const g2float alog2=0.69314718f;       //  ln(2.0)
      70             : 
      71          65 :       bscale=(float)int_power(2.0,-idrstmpl[1]);
      72          65 :       dscale=(float)int_power(10.0,idrstmpl[2]);
      73          65 :       if (idrstmpl[3] <= 0 || idrstmpl[3] > 31)
      74          55 :          nbits=0;
      75             :       else
      76          10 :          nbits=idrstmpl[3];
      77             : 
      78          65 :       if( dscale == 0.0 )
      79             :       {
      80           0 :           fprintf(stderr, "Invalid dscale == 0 value\n");
      81           0 :           *lcpack = -1;
      82           0 :           return;
      83             :       }
      84             : //
      85             : //  Find max and min values in the data
      86             : //
      87          65 :       rmax=fld[0];
      88          65 :       rmin=fld[0];
      89       60456 :       for (j=1;j<ndpts;j++) {
      90       60391 :         if (fld[j] > rmax) rmax=fld[j];
      91       60391 :         if (fld[j] < rmin) rmin=fld[j];
      92             :       }
      93          65 :       if( !(floor((double)rmin*dscale) >= -FLT_MAX && floor((double)rmin*dscale) <= FLT_MAX) )
      94             :       {
      95           0 :          fprintf(stderr,
      96             :                     "Scaled min value not representable on IEEE754 "
      97             :                     "single precision float\n");
      98           0 :         *lcpack = -1;
      99           0 :         return;
     100             :       }
     101          65 :       if( !(floor((double)rmax*dscale) >= -FLT_MAX && floor((double)rmax*dscale) <= FLT_MAX) )
     102             :       {
     103           0 :          fprintf(stderr,
     104             :                     "Scaled max value not representable on IEEE754 "
     105             :                     "single precision float\n");
     106           0 :         *lcpack = -1;
     107           0 :         return;
     108             :       }
     109          65 :       rmin_dscaled = rmin*dscale;
     110          65 :       rmax_dscaled = rmax*dscale;
     111             : 
     112          65 :       ifld=calloc(ndpts,sizeof(g2int));
     113          65 :       if( ifld == NULL )
     114             :       {
     115           0 :           fprintf(stderr, "Cannot allocate ifld in simpack()\n");
     116           0 :           *lcpack = -1;
     117           0 :           return;
     118             :       }
     119             : 
     120             : //
     121             : //  If max and min values are not equal, pack up field.
     122             : //  If they are equal, we have a constant field, and the reference
     123             : //  value (rmin) is the value for each point in the field and
     124             : //  set nbits to 0.
     125             : //
     126          65 :       if ( (rmax_dscaled - rmin_dscaled >= 1) ||
     127           2 :            (rmin != rmax && nbits!=0 && idrstmpl[1]==0) ) {
     128          34 :         int done = 0;
     129             :         //
     130             :         //  Determine which algorithm to use based on user-supplied
     131             :         //  binary scale factor and number of bits.
     132             :         //
     133          34 :         if (nbits==0 && idrstmpl[1]==0) {
     134             :            //
     135             :            //  No binary scaling and calculate minimum number of
     136             :            //  bits in which the data will fit.
     137             :            //
     138          24 :            if( dscale != 1.0 )
     139             :            {
     140           1 :               rmin_dscaled = (float)floor(rmin_dscaled);
     141             :            }
     142          24 :            if( (double)(rmax_dscaled - rmin_dscaled) > (double)INT_MAX )
     143             :            {
     144           1 :                 nbits = 31;
     145             :            }
     146             :            else
     147             :            {
     148          23 :                 temp=(float)(log(ceil(rmax_dscaled - rmin_dscaled))/alog2);
     149          23 :                 nbits=(g2int)ceil(temp);
     150             :                 //   scale data
     151          23 :                 if( nbits > 31 )
     152             :                 {
     153           0 :                     nbits = 31;
     154             :                 }
     155             :                 else
     156             :                 {
     157          23 :                     done = 1;
     158        9499 :                     for(j=0;j<ndpts;j++)
     159        9476 :                         ifld[j]=(g2int)RINT(fld[j]*dscale -rmin_dscaled);
     160          23 :                     ref = rmin_dscaled;
     161             :                 }
     162             :            }
     163             :         }
     164             : 
     165          34 :         if (!done && nbits!=0 && idrstmpl[1]==0) {
     166             :            //
     167             :            //  Use number of bits specified by user and
     168             :            //  adjust binary scaling factor to accommodate data.
     169             :            //
     170          11 :            if( dscale != 1.0 )
     171             :            {
     172           4 :               rmin_dscaled = (float)floor(rmin_dscaled);
     173             :            }
     174          11 :            maxnum=int_power(2.0,nbits)-1;
     175          11 :            temp=(float)(log(maxnum/(rmax_dscaled-rmin_dscaled))/alog2);
     176          11 :            idrstmpl[1]=(g2int)ceil(-1.0*temp);
     177          11 :            bscale=(float)int_power(2.0,-idrstmpl[1]);
     178             :            //   scale data
     179       48089 :            for (j=0;j<ndpts;j++)
     180       48078 :              ifld[j]=(g2int)RINT(((fld[j]*dscale)-rmin_dscaled)*bscale);
     181          11 :            ref=rmin_dscaled;
     182             :         }
     183          23 :         else if (nbits==0 && idrstmpl[1]!=0) {
     184             :            //
     185             :            //  Use binary scaling factor and calculate minimum number of
     186             :            //  bits in which the data will fit.
     187             :            //
     188           0 :            maxdif=(g2int)RINT((rmax_dscaled-rmin_dscaled)*bscale);
     189           0 :            temp=(float)(log((double)(maxdif+1))/alog2);
     190           0 :            nbits=(g2int)ceil(temp);
     191             :            //   scale data
     192           0 :            for (j=0;j<ndpts;j++)
     193           0 :              ifld[j]=(g2int)RINT(((fld[j]*dscale)-rmin_dscaled)*bscale);
     194           0 :            ref=rmin_dscaled;
     195             :         }
     196          23 :         else if (nbits!=0 && idrstmpl[1]!=0) {
     197             :            //
     198             :            //  Use binary scaling factor and use minimum number of
     199             :            //  bits specified by user.   Dangerous - may loose
     200             :            //  information if binary scale factor and nbits not set
     201             :            //  properly by user.
     202             :            //
     203             :            //   scale data
     204           0 :            for (j=0;j<ndpts;j++)
     205           0 :              ifld[j]=(g2int)RINT(((fld[j]*dscale)-rmin_dscaled)*bscale);
     206           0 :            ref=rmin_dscaled;
     207             :         }
     208             :         //
     209             :         //  Pack data, Pad last octet with Zeros, if necessary,
     210             :         //  and calculate the length of the packed data in bytes
     211             :         //
     212          34 :         sbits(cpack,ifld+0,0,nbits,0,ndpts);
     213          34 :         nbittot=nbits*ndpts;
     214          34 :         left=8-(nbittot%8);
     215          34 :         if (left != 8) {
     216           3 :           sbit(cpack,&zero,nbittot,left);   // Pad with zeros to fill Octet
     217           3 :           nbittot=nbittot+left;
     218             :         }
     219          34 :         *lcpack=nbittot/8;
     220             :       }
     221             :       else {
     222             :         /* Force E and D to 0 to avoid compatibility issues */
     223          31 :         idrstmpl[1]=0;
     224          31 :         idrstmpl[2]=0;
     225          31 :         if( dscale != 1.0 )
     226             :         {
     227           0 :           ref = (float)floor((double)rmin * dscale) / dscale;
     228             :         }
     229             :         else
     230             :         {
     231          31 :           ref = rmin;
     232             :         }
     233          31 :         nbits=0;
     234          31 :         *lcpack=0;
     235             :       }
     236             : 
     237             : //
     238             : //  Fill in ref value and number of bits in Template 5.0
     239             : //
     240             :       //printf("SAGmkieee %f\n",ref);
     241          65 :       mkieee(&ref,idrstmpl+0,1);   // ensure reference value is IEEE format
     242             :       //printf("SAGmkieee %ld\n",idrstmpl[0]);
     243          65 :       idrstmpl[3]=nbits;
     244          65 :       idrstmpl[4]=0;         // original data were reals
     245             : 
     246          65 :       free(ifld);
     247             : }

Generated by: LCOV version 1.14