diff --git a/src/grib_bits_any_endian_vector.c b/src/grib_bits_any_endian_vector.c index f8e29af79..01ca02c47 100644 --- a/src/grib_bits_any_endian_vector.c +++ b/src/grib_bits_any_endian_vector.c @@ -10,16 +10,15 @@ /*************************************************************************** * Enrico Fucile - 19.06.2007 * - * EXPERIMENTAL CODE - NOT FULLY TESTED * + * * ***************************************************************************/ - int grib_decode_long_array(const unsigned char* p, long* bitp, long bitsPerValue, size_t n_vals, long* val) { long i = 0; unsigned long lvalue = 0; - /* SUP-3196: Thanks to Daniel Tameling */ + /* if (bitsPerValue % 8) { */ if (bitsPerValue % 8 || (*bitp & 7)) { int j = 0; for (i = 0; i < n_vals; i++) { @@ -55,6 +54,7 @@ int grib_decode_long_array(const unsigned char* p, long* bitp, long bitsPerValue return 0; } + int grib_decode_double_array(const unsigned char* p, long* bitp, long bitsPerValue, double reference_value, double s, double d, size_t n_vals, double* val) @@ -96,14 +96,12 @@ int grib_decode_double_array(const unsigned char* p, long* bitp, long bitsPerVal return 0; } -int grib_decode_double_array_complex(const unsigned char* p, long* bitp, long nbits, double reference_value, - double s, double* d, size_t size, double* val) +int grib_decode_double_array_complex(const unsigned char* p, long* bitp, long nbits, double reference_value, double s, double* d, size_t size, double* val) { return GRIB_NOT_IMPLEMENTED; } -int grib_encode_double_array(size_t n_vals, const double* val, long bits_per_value, double reference_value, - double d, double divisor, unsigned char* p, long* off) +int grib_encode_double_array(size_t n_vals, const double* val, long bits_per_value, double reference_value, double d, double divisor, unsigned char* p, long* off) { size_t i = 0; unsigned long unsigned_val = 0; @@ -115,17 +113,50 @@ int grib_encode_double_array(size_t n_vals, const double* val, long bits_per_val } } else { - for (i = 0; i < n_vals; i++) { - int blen = 0; - blen = bits_per_value; - unsigned_val = (unsigned long)((((val[i] * d) - reference_value) * divisor) + 0.5); - while (blen >= 8) { - blen -= 8; - *encoded = (unsigned_val >> blen); - encoded++; - *off += 8; - } + if (bits_per_value == 16 && !((uint64_t)p&3)) { + uint32_t *encoded4byte = (uint32_t *) p; + uint32_t tmp; + unsigned long unsigned_val2 = 0; + for(i = 0; i < n_vals - 1; i+=2){ + unsigned_val = (unsigned long)((((val[i]*d)-reference_value)*divisor)+0.5); + unsigned_val2 = (unsigned long)((((val[i+1]*d)-reference_value)*divisor)+0.5); + tmp = (unsigned_val2 & 0xff); + tmp = (tmp << 8) + (unsigned_val2 >> 8 & 0xff); + tmp = (tmp << 8) + (unsigned_val & 0xff); + tmp = (tmp << 8) + ((unsigned_val >> 8) & 0xff); + *encoded4byte = tmp; + encoded4byte++; + *off+=32; } + /* remainder */ + if (n_vals % 2) { + int blen = 0; + i = n_vals-1; + encoded = (unsigned char *) encoded4byte; + blen = bits_per_value; + unsigned_val = (unsigned long)((((val[i]*d)-reference_value)*divisor)+0.5); + while(blen >= 8) + { + blen -= 8; + *encoded = (unsigned_val >> blen); + encoded++; + *off+=8; + } + } + } + else { + for (i = 0; i < n_vals; i++) { + int blen = 0; + blen = bits_per_value; + unsigned_val = (unsigned long)((((val[i] * d) - reference_value) * divisor) + 0.5); + while (blen >= 8) { + blen -= 8; + *encoded = (unsigned_val >> blen); + encoded++; + *off += 8; + } + } + } } return GRIB_SUCCESS; }