1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
#include "stdlib.h"
/*
----------------------------------------------------------------------
----------------------------------------------------------------------
This routine reads any number of bits starting at any adress
within a byte and outputs it as an 32-bits integer.
It's the basic stone of the GRIB format decoding.
----------------------------------------------------------------------
----------------------------------------------------------------------
*/
void Grib_Get_Bits_From_Bytes ( char *Message,
int *Stockage,
int Adresse,
int Nbits )
{
int I_Depart, I_Origine, I_End ;
int N_Car, I_Equiv, I, J, I_Start, Ko, K1 ;
char Buffer ;
/*
--- Gets the starting bit, and the number of bytes to be read
*/
I_Depart = Adresse / 8 ;
I_Origine = Adresse - I_Depart*8 ;
if ( Nbits > 8 )
N_Car = 1 + (Nbits-1)/8 ;
else
if ( (I_Origine+Nbits) > 8 )
N_Car = 2 ;
else
N_Car = 1 ;
/*
--- Gets the number of bits to be read in the last byte
*/
Ko = 8 ;
/* Correction JS 28/06/2000 : incorrect formula */
if ( (Nbits/8)*8 != Nbits ) /* Nbits modulo 8 != 0 */
{
if ( N_Car > 1 )
Ko = 8 - (8*N_Car - (I_Origine + Nbits)) ;
else
Ko = I_Origine+Nbits ;
}
I_Equiv = 0 ;
/*
--- If there are several bits to be retrieved
*/
if ( Nbits != 1 )
{
/*
Reads them and stores them at the right place relative to weights
*/
for ( I = 1 ; I <= N_Car ; I++ )
{
Buffer = *(Message+I_Depart+I-1) ;
if ( (I == 1) && (I_Origine != 0) )
I_Start = I_Origine ;
else
I_Start = 0 ;
if ( ( I == N_Car) && (Ko != 8) )
I_End = Ko ;
else
I_End = 8 ;
for ( J = I_Start ; J < I_End ; J++ )
{
if ( getbitbyte(&Buffer, 7-J) == 1 )
{
setbit ( &I_Equiv, (7-J)+(N_Car-I)*8 );
}
}
}
/*
If we are not finishing on byte boundary, resets the end of the byte
*/
if ( Ko != 8 )
{
J = I_Equiv ;
I_Equiv = 0 ;
for ( I = Ko ; I < (8*sizeof(int)) ; I++ )
{
K1 = getbit ( &J, I );
if ( K1 == 1 ) setbit ( &I_Equiv, (I-Ko) );
}
}
}
/*
--- If only one bit to retrieve
*/
else
{
Buffer = *(Message+I_Depart);
if ( getbitbyte ( &Buffer, 7-I_Origine ) == 1 )
setbit ( &I_Equiv, 0 ) ;
}
*Stockage = I_Equiv ;
}
/*
----------------------------------------------------------------------
Gets bit # Numero in integer Entier
----------------------------------------------------------------------
*/
int getbit ( int *Entier,
int Numero )
{
return ((*Entier >> Numero) & ~(~0 << 1)) ;
}
/*
----------------------------------------------------------------------
Gets bit # Numero in byte Byte
----------------------------------------------------------------------
*/
int getbitbyte ( char *Byte,
int Numero )
{
return ((*Byte >> (Numero)) & ~(~0 << 1)) ;
}
/*
----------------------------------------------------------------------
Sets bit # Numero in integer Entier
----------------------------------------------------------------------
*/
void setbit ( int *Entier,
int Numero )
{
*Entier = *Entier | (1 << Numero) ;
} |