2013-03-25 12:04:10 +00:00
|
|
|
/*
|
2015-01-05 15:45:46 +00:00
|
|
|
* Copyright 2005-2015 ECMWF.
|
2013-03-25 12:04:10 +00:00
|
|
|
*
|
|
|
|
* This software is licensed under the terms of the Apache Licence Version 2.0
|
|
|
|
* which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
|
|
|
*
|
|
|
|
* In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
|
|
|
|
* virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* Enrico Fucile - 19.06.2007 *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
|
2014-06-21 11:19:15 +00:00
|
|
|
typedef struct bits_all_one_t {
|
|
|
|
int inited;
|
|
|
|
int size;
|
|
|
|
long v[128];
|
|
|
|
} bits_all_one_t;
|
|
|
|
|
|
|
|
static bits_all_one_t bits_all_one={0,0,{0,}};
|
|
|
|
|
|
|
|
static void init_bits_all_one() {
|
|
|
|
int size=sizeof(long)*8;
|
|
|
|
long* v=0;
|
|
|
|
unsigned long cmask=-1;
|
|
|
|
bits_all_one.size=size;
|
|
|
|
bits_all_one.inited=1;
|
|
|
|
v=bits_all_one.v+size;
|
|
|
|
*v= cmask << size;
|
|
|
|
while (size>0) *(--v)= ~(cmask << --size);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int grib_is_all_bits_one(long val, long nbits) {
|
|
|
|
|
|
|
|
if (!bits_all_one.inited) init_bits_all_one();
|
|
|
|
return bits_all_one.v[nbits]==val;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-06-03 13:52:29 +00:00
|
|
|
int grib_encode_string(const unsigned char* bitStream, long *bitOffset, size_t numberOfCharacters,char* string)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
int err=0;
|
|
|
|
long byteOffset = *bitOffset / 8;
|
|
|
|
int remainder = *bitOffset % 8;
|
|
|
|
unsigned char c;
|
|
|
|
unsigned char* p;
|
|
|
|
char* s=string;
|
|
|
|
unsigned char mask[] ={ 0, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
|
|
|
|
int remainderComplement=8-remainder;
|
|
|
|
|
2015-06-18 10:22:16 +00:00
|
|
|
if (remainder) byteOffset++;
|
|
|
|
|
2015-06-03 13:52:29 +00:00
|
|
|
if (numberOfCharacters==0) return err;
|
|
|
|
|
|
|
|
p=(unsigned char*)bitStream+byteOffset;
|
|
|
|
|
|
|
|
if ( remainder == 0 ) {
|
|
|
|
memcpy(p,string,numberOfCharacters);
|
|
|
|
*bitOffset+=numberOfCharacters*8;
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i=0;i<numberOfCharacters;i++) {
|
|
|
|
c=(*s)>>remainderComplement;
|
|
|
|
*p |= c;
|
|
|
|
p++;
|
|
|
|
*p = (*s) & mask[remainder];
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
*bitOffset+=numberOfCharacters*8;
|
|
|
|
return err;
|
|
|
|
}
|
2014-06-21 11:19:15 +00:00
|
|
|
|
|
|
|
char* grib_decode_string(const unsigned char* bitStream, long *bitOffset, size_t numberOfCharacters,char* string)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
long byteOffset = *bitOffset / 8;
|
|
|
|
int remainder = *bitOffset % 8;
|
|
|
|
unsigned char c;
|
|
|
|
unsigned char* p;
|
|
|
|
char* s=string;
|
|
|
|
unsigned char mask[] ={ 0, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
|
|
|
|
int remainderComplement=8-remainder;
|
|
|
|
|
|
|
|
if (numberOfCharacters==0) return string;
|
|
|
|
|
|
|
|
p=(unsigned char*)bitStream+byteOffset;
|
|
|
|
|
|
|
|
if ( remainder == 0 ) {
|
|
|
|
memcpy(string,bitStream+byteOffset,numberOfCharacters);
|
|
|
|
*bitOffset+=numberOfCharacters*8;
|
|
|
|
return string;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i=0;i<numberOfCharacters;i++) {
|
|
|
|
c=(*p)<<remainder;
|
|
|
|
p++;
|
|
|
|
*s = ( c | ( (*p) & mask[remainder] )>>remainderComplement );
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
*bitOffset+=numberOfCharacters*8;
|
|
|
|
return string;
|
|
|
|
}
|
2013-03-25 12:04:10 +00:00
|
|
|
|
|
|
|
unsigned long grib_decode_unsigned_long(const unsigned char* p, long *bitp, long nbits)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
long ret = 0;
|
|
|
|
long o = *bitp/8;
|
|
|
|
int l = nbits/8;
|
|
|
|
|
|
|
|
if (nbits==0) return 0;
|
|
|
|
|
|
|
|
if(nbits > max_nbits)
|
|
|
|
{
|
|
|
|
int bits = nbits;
|
|
|
|
int mod = bits % max_nbits;
|
|
|
|
|
|
|
|
if(mod != 0)
|
|
|
|
{
|
|
|
|
int e=grib_decode_unsigned_long(p,bitp,mod);
|
|
|
|
Assert( e == 0);
|
|
|
|
bits -= mod;
|
|
|
|
}
|
|
|
|
|
|
|
|
while(bits > max_nbits)
|
|
|
|
{
|
|
|
|
int e=grib_decode_unsigned_long(p,bitp,max_nbits);
|
|
|
|
Assert( e == 0);
|
|
|
|
bits -= max_nbits;
|
|
|
|
}
|
|
|
|
|
|
|
|
return grib_decode_unsigned_long(p,bitp,bits);
|
|
|
|
}
|
|
|
|
|
|
|
|
if((nbits%8 > 0)||(*bitp%8 > 0)) {
|
|
|
|
for(i=0; i< nbits;i++){
|
|
|
|
ret <<= 1;
|
|
|
|
if(grib_get_bit( p, *bitp)) ret += 1;
|
|
|
|
*bitp += 1;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret <<= 8;
|
|
|
|
ret |= p[o++] ;
|
|
|
|
|
|
|
|
for ( i=1; i<l; i++ )
|
|
|
|
{
|
|
|
|
ret <<= 8;
|
|
|
|
ret |= p[o++] ;
|
|
|
|
}
|
|
|
|
*bitp += nbits;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int grib_encode_unsigned_long(unsigned char* p, unsigned long val ,long *bitp, long nbits)
|
|
|
|
{
|
|
|
|
long len = nbits;
|
|
|
|
int s = *bitp % 8;
|
|
|
|
int n = 8 - s;
|
|
|
|
unsigned char tmp = 0; /*for temporary results*/
|
|
|
|
|
|
|
|
if (nbits > max_nbits) {
|
|
|
|
/* TODO: Do some real code here, to support long longs */
|
|
|
|
int bits = nbits;
|
|
|
|
int mod = bits % max_nbits;
|
|
|
|
long zero = 0;
|
|
|
|
|
|
|
|
if (mod != 0) {
|
|
|
|
int e = grib_encode_unsigned_long(p, zero, bitp, mod);
|
|
|
|
/* printf(" -> : encoding %ld bits=%ld %ld\n",zero,(long)mod,*bitp); */
|
|
|
|
Assert(e == 0);
|
|
|
|
bits -= mod;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (bits > max_nbits) {
|
|
|
|
int e = grib_encode_unsigned_long(p, zero, bitp, max_nbits);
|
|
|
|
/* printf(" -> : encoding %ld bits=%ld %ld\n",zero,(long)max_nbits,*bitp); */
|
|
|
|
Assert(e == 0);
|
|
|
|
bits -= max_nbits;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* printf(" -> : encoding %ld bits=%ld %ld\n",val,(long)bits,*bitp); */
|
|
|
|
return grib_encode_unsigned_long(p, val, bitp, bits);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (s)
|
|
|
|
p += (*bitp >> 3); /* skip the bytes */
|
|
|
|
else
|
|
|
|
p += (*bitp >> 3); /* skip the bytes */
|
|
|
|
|
|
|
|
/* head */
|
|
|
|
if (s) {
|
|
|
|
len -= n;
|
|
|
|
if (len < 0) {
|
|
|
|
tmp = ((val << -len) | ((*p) & dmasks[n]));
|
|
|
|
} else {
|
|
|
|
tmp = ((val >> len) | ((*p) & dmasks[n]));
|
|
|
|
}
|
|
|
|
*p = tmp;
|
|
|
|
(*p)++;
|
|
|
|
|
|
|
|
/*Beware of code like this! compiler warning: operation may be undefined
|
|
|
|
Read GCC manual on -Wsequence-point*/
|
|
|
|
/* *p = ((val << -len) | ((*p)++ & dmasks[n])); */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* write the middle words */
|
|
|
|
while (len >= 8) {
|
|
|
|
len -= 8;
|
|
|
|
*p++ = (val >> len);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* write the end bits */
|
|
|
|
if (len)
|
|
|
|
*p = (val << (8 - len));
|
|
|
|
|
|
|
|
*bitp += nbits;
|
|
|
|
return GRIB_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int grib_encode_unsigned_longb(unsigned char* p, unsigned long val ,long *bitp, long nb)
|
|
|
|
{
|
|
|
|
long i = 0;
|
|
|
|
|
|
|
|
if (nb > max_nbits) {
|
|
|
|
fprintf(stderr, "Number of bits (%ld) exceeds maximum number of bits (%d)\n", nb, max_nbits);
|
|
|
|
Assert(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(i=nb-1; i >= 0; i--){
|
|
|
|
if(test(val,i))
|
|
|
|
grib_set_bit_on (p, bitp);
|
|
|
|
else
|
|
|
|
grib_set_bit_off(p, bitp);
|
|
|
|
}
|
|
|
|
return GRIB_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if OMP_PACKING
|
|
|
|
|
|
|
|
#include "grib_bits_any_endian_omp.c"
|
|
|
|
|
|
|
|
#elif VECTOR
|
|
|
|
|
|
|
|
#include "grib_bits_any_endian_vector.c"
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
#include "grib_bits_any_endian_simple.c"
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|