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