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