LCOV - code coverage report
Current view: top level - frmts/grib/degrib/g2clib - gbits.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 64 66 97.0 %
Date: 2024-05-06 13:02:59 Functions: 5 5 100.0 %

          Line data    Source code
       1             : #include "grib2.h"
       2             : #include "limits.h"
       3             : 
       4       29621 : int gbit(unsigned char *in,g2int *iout,g2int iskip,g2int nbyte)
       5             : {
       6       29621 :       return gbits(in,G2_UNKNOWN_SIZE,iout,iskip,nbyte,(g2int)0,(g2int)1);
       7             : }
       8             : 
       9       40908 : int gbit2(unsigned char *in,g2int in_length,g2int *iout,g2int iskip,g2int nbyte)
      10             : {
      11       40908 :       return gbits(in,in_length,iout,iskip,nbyte,(g2int)0,(g2int)1);
      12             : }
      13             : 
      14          48 : void sbit(unsigned char *out,const g2int *in,g2int iskip,g2int nbyte)
      15             : {
      16          48 :       sbits(out,in,iskip,nbyte,(g2int)0,(g2int)1);
      17          48 : }
      18             : 
      19             : 
      20      163914 : int gbits(unsigned char *in,g2int in_length,g2int *iout,g2int iskip,g2int nbyte,g2int nskip,
      21             :            g2int n)
      22             : /*          Get bits - unpack bits:  Extract arbitrary size values from a
      23             : /          packed bit string, right justifying each value in the unpacked
      24             : /          iout array.
      25             : /           *in    = pointer to character array input
      26             : /           *iout  = pointer to unpacked array output
      27             : /            iskip = initial number of bits to skip
      28             : /            nbyte = number of bits to take
      29             : /            nskip = additional number of bits to skip on each iteration
      30             : /            n     = number of iterations
      31             : / v1.1
      32             : */
      33             : {
      34             :       g2int i,tbit,bitcnt,ibit,itmp;
      35             :       g2int nbit,l_index;
      36             :       static const g2int ones[]={1,3,7,15,31,63,127,255};
      37             : 
      38             : //     nbit is the start position of the field in bits
      39      163914 :       nbit = iskip;
      40      163914 :       if( n> 0 && (nbyte + nskip > INT_MAX / n ||
      41      163914 :                    iskip > INT_MAX - n*(nbyte + nskip)) )
      42           0 :           return -1;
      43     6831160 :       for (i=0;i<n;i++) {
      44     6667250 :          bitcnt = nbyte;
      45     6667250 :          l_index=nbit/8;
      46     6667250 :          ibit=nbit%8;
      47     6667250 :          nbit = nbit + nbyte + nskip;
      48             : 
      49             : //        first byte
      50     6667250 :          tbit= ( bitcnt < (8-ibit) ) ? bitcnt : 8-ibit;  // find min
      51     6667250 :          if( in_length != G2_UNKNOWN_SIZE && l_index >= in_length )
      52           4 :              return -1;
      53     6667250 :          itmp = (int)*(in+l_index) & ones[7-ibit];
      54     6667250 :          if (tbit != 8-ibit) itmp >>= (8-ibit-tbit);
      55     6667250 :          l_index++;
      56     6667250 :          bitcnt = bitcnt - tbit;
      57             : 
      58             : //        now transfer whole bytes
      59    11669300 :          while (bitcnt >= 8) {
      60     5002090 :             if( in_length != G2_UNKNOWN_SIZE && l_index >= in_length )
      61           1 :                 return -1;
      62     5002090 :              itmp = (int)(((unsigned)itmp)<<8 | (int)*(in+l_index));
      63     5002090 :              bitcnt = bitcnt - 8;
      64     5002090 :              l_index++;
      65             :          }
      66             : 
      67             : //        get data from last byte
      68     6667240 :          if (bitcnt > 0) {
      69      473132 :             if( in_length != G2_UNKNOWN_SIZE && l_index >= in_length )
      70           0 :                 return -1;
      71      473132 :              itmp = (int)( (unsigned)itmp << bitcnt ) | ( ((int)*(in+l_index) >> (8-bitcnt)) & ones[bitcnt-1] );
      72             :          }
      73             : 
      74     6667240 :          *(iout+i) = itmp;
      75             :       }
      76             : 
      77      163909 :       return 0;
      78             : }
      79             : 
      80             : 
      81       36252 : void sbits(unsigned char *out,const g2int *in,g2int iskip,g2int nbyte,g2int nskip,
      82             :            g2int n)
      83             : /*C          Store bits - pack bits:  Put arbitrary size values into a
      84             : /          packed bit string, taking the low order bits from each value
      85             : /          in the unpacked array.
      86             : /           *iout  = pointer to packed array output
      87             : /           *in    = pointer to unpacked array input
      88             : /            iskip = initial number of bits to skip
      89             : /            nbyte = number of bits to pack
      90             : /            nskip = additional number of bits to skip on each iteration
      91             : /            n     = number of iterations
      92             : / v1.1
      93             : */
      94             : {
      95             :       g2int i;
      96             :       unsigned bitcnt,tbit,ibit,itmp,imask,itmp2,itmp3;
      97             :       unsigned nbit,l_index;
      98             :       static const unsigned ones[]={1,3,7,15,31,63,127,255};
      99       36252 :       const unsigned* u_in = (const unsigned*)in;
     100             : 
     101             : //     number bits from zero to ...
     102             : //     nbit is the last bit of the field to be filled
     103             : 
     104       36252 :       nbit = iskip + nbyte - 1;
     105      676260 :       for (i=0;i<n;i++) {
     106      640008 :          itmp = *(u_in+i);
     107      640008 :          bitcnt = nbyte;
     108      640008 :          l_index=nbit/8;
     109      640008 :          ibit=nbit%8;
     110      640008 :          nbit = nbit + nbyte + nskip;
     111             : 
     112             : //        make byte aligned
     113      640008 :          if (ibit != 7) {
     114      496923 :              tbit= ( bitcnt < (ibit+1) ) ? bitcnt : ibit+1;  // find min
     115      496923 :              imask = ones[tbit-1] << (7-ibit);
     116      496923 :              itmp2 = (itmp << (7-ibit)) & imask;
     117      496923 :              itmp3 = (int)*(out+l_index) & (255-imask);
     118      496923 :              out[l_index] = (unsigned char)(itmp2 | itmp3);
     119      496923 :              bitcnt = bitcnt - tbit;
     120      496923 :              itmp = itmp >> tbit;
     121      496923 :              if( bitcnt > 0 )
     122      205310 :                 l_index--;
     123             :          }
     124             : 
     125             : //        now byte aligned
     126             : 
     127             : //        do by bytes
     128      702758 :          while (bitcnt >= 8) {
     129       62750 :              out[l_index] = (unsigned char)(itmp & 255);
     130       62750 :              itmp = itmp >> 8;
     131       62750 :              bitcnt = bitcnt - 8;
     132       62750 :              if( bitcnt > 0 )
     133        6249 :                 l_index--;
     134             :          }
     135             : 
     136             : //        do last byte
     137             : 
     138      640008 :          if (bitcnt > 0) {
     139      291894 :              itmp2 = itmp & ones[bitcnt-1];
     140      291894 :              itmp3 = (int)*(out+l_index) & (255-ones[bitcnt-1]);
     141      291894 :              out[l_index] = (unsigned char)(itmp2 | itmp3);
     142             :          }
     143             :       }
     144             : 
     145       36252 : }

Generated by: LCOV version 1.14