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