Line data Source code
1 : #include "grib2.h"
2 : #include "limits.h"
3 :
4 30407 : int gbit(unsigned char *in,g2int *iout,g2int iskip,g2int nbyte)
5 : {
6 30407 : return gbits(in,G2_UNKNOWN_SIZE,iout,iskip,nbyte,(g2int)0,(g2int)1);
7 : }
8 :
9 41760 : int gbit2(unsigned char *in,g2int in_length,g2int *iout,g2int iskip,g2int nbyte)
10 : {
11 41760 : 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 165552 : 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 165552 : nbit = iskip;
40 165552 : if( n> 0 && (nbyte + nskip > INT_MAX / n ||
41 165552 : iskip > INT_MAX - n*(nbyte + nskip)) )
42 0 : return -1;
43 6834440 : for (i=0;i<n;i++) {
44 6668890 : bitcnt = nbyte;
45 6668890 : l_index=nbit/8;
46 6668890 : ibit=nbit%8;
47 6668890 : nbit = nbit + nbyte + nskip;
48 :
49 : // first byte
50 6668890 : tbit= ( bitcnt < (8-ibit) ) ? bitcnt : 8-ibit; // find min
51 6668890 : if( in_length != G2_UNKNOWN_SIZE && l_index >= in_length )
52 4 : return -1;
53 6668880 : itmp = (int)*(in+l_index) & ones[7-ibit];
54 6668880 : if (tbit != 8-ibit) itmp >>= (8-ibit-tbit);
55 6668880 : l_index++;
56 6668880 : bitcnt = bitcnt - tbit;
57 :
58 : // now transfer whole bytes
59 11672600 : while (bitcnt >= 8) {
60 5003720 : if( in_length != G2_UNKNOWN_SIZE && l_index >= in_length )
61 1 : return -1;
62 5003720 : itmp = (int)(((unsigned)itmp)<<8 | (int)*(in+l_index));
63 5003720 : bitcnt = bitcnt - 8;
64 5003720 : l_index++;
65 : }
66 :
67 : // get data from last byte
68 6668880 : 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 6668880 : *(iout+i) = itmp;
75 : }
76 :
77 165547 : 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 : }
|