1 #include "grib2.h"
2 #include "limits.h"
3 
gbit(unsigned char * in,g2int * iout,g2int iskip,g2int nbyte)4 int gbit(unsigned char *in,g2int *iout,g2int iskip,g2int nbyte)
5 {
6       return gbits(in,G2_UNKNOWN_SIZE,iout,iskip,nbyte,(g2int)0,(g2int)1);
7 }
8 
gbit2(unsigned char * in,g2int in_length,g2int * iout,g2int iskip,g2int nbyte)9 int gbit2(unsigned char *in,g2int in_length,g2int *iout,g2int iskip,g2int nbyte)
10 {
11       return gbits(in,in_length,iout,iskip,nbyte,(g2int)0,(g2int)1);
12 }
13 
sbit(unsigned char * out,const g2int * in,g2int iskip,g2int nbyte)14 void sbit(unsigned char *out,const g2int *in,g2int iskip,g2int nbyte)
15 {
16       sbits(out,in,iskip,nbyte,(g2int)0,(g2int)1);
17 }
18 
19 
gbits(unsigned char * in,g2int in_length,g2int * iout,g2int iskip,g2int nbyte,g2int nskip,g2int n)20 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       nbit = iskip;
40       if( n> 0 && (nbyte + nskip > INT_MAX / n ||
41                    iskip > INT_MAX - n*(nbyte + nskip)) )
42           return -1;
43       for (i=0;i<n;i++) {
44          bitcnt = nbyte;
45          l_index=nbit/8;
46          ibit=nbit%8;
47          nbit = nbit + nbyte + nskip;
48 
49 //        first byte
50          tbit= ( bitcnt < (8-ibit) ) ? bitcnt : 8-ibit;  // find min
51          if( in_length != G2_UNKNOWN_SIZE && l_index >= in_length )
52              return -1;
53          itmp = (int)*(in+l_index) & ones[7-ibit];
54          if (tbit != 8-ibit) itmp >>= (8-ibit-tbit);
55          l_index++;
56          bitcnt = bitcnt - tbit;
57 
58 //        now transfer whole bytes
59          while (bitcnt >= 8) {
60             if( in_length != G2_UNKNOWN_SIZE && l_index >= in_length )
61                 return -1;
62              itmp = (int)(((unsigned)itmp)<<8 | (int)*(in+l_index));
63              bitcnt = bitcnt - 8;
64              l_index++;
65          }
66 
67 //        get data from last byte
68          if (bitcnt > 0) {
69             if( in_length != G2_UNKNOWN_SIZE && l_index >= in_length )
70                 return -1;
71              itmp = (int)( (unsigned)itmp << bitcnt ) | ( ((int)*(in+l_index) >> (8-bitcnt)) & ones[bitcnt-1] );
72          }
73 
74          *(iout+i) = itmp;
75       }
76 
77       return 0;
78 }
79 
80 
sbits(unsigned char * out,const g2int * in,g2int iskip,g2int nbyte,g2int nskip,g2int n)81 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       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       nbit = iskip + nbyte - 1;
105       for (i=0;i<n;i++) {
106          itmp = *(u_in+i);
107          bitcnt = nbyte;
108          l_index=nbit/8;
109          ibit=nbit%8;
110          nbit = nbit + nbyte + nskip;
111 
112 //        make byte aligned
113          if (ibit != 7) {
114              tbit= ( bitcnt < (ibit+1) ) ? bitcnt : ibit+1;  // find min
115              imask = ones[tbit-1] << (7-ibit);
116              itmp2 = (itmp << (7-ibit)) & imask;
117              itmp3 = (int)*(out+l_index) & (255-imask);
118              out[l_index] = (unsigned char)(itmp2 | itmp3);
119              bitcnt = bitcnt - tbit;
120              itmp = itmp >> tbit;
121              if( bitcnt > 0 )
122                 l_index--;
123          }
124 
125 //        now byte aligned
126 
127 //        do by bytes
128          while (bitcnt >= 8) {
129              out[l_index] = (unsigned char)(itmp & 255);
130              itmp = itmp >> 8;
131              bitcnt = bitcnt - 8;
132              if( bitcnt > 0 )
133                 l_index--;
134          }
135 
136 //        do last byte
137 
138          if (bitcnt > 0) {
139              itmp2 = itmp & ones[bitcnt-1];
140              itmp3 = (int)*(out+l_index) & (255-ones[bitcnt-1]);
141              out[l_index] = (unsigned char)(itmp2 | itmp3);
142          }
143       }
144 
145 }
146