mirror of https://github.com/ecmwf/eccodes.git
ECC-1467: Debugging
This commit is contained in:
parent
78af61b989
commit
4dd790f2ff
|
@ -1,19 +1,3 @@
|
|||
/*
|
||||
* (C) Copyright 2005- ECMWF.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* C Implementation: grib_get_keys
|
||||
*
|
||||
* Description: how to get values using keys from GRIB messages
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
@ -22,26 +6,14 @@
|
|||
int main(int argc, char** argv)
|
||||
{
|
||||
int err = 0;
|
||||
double* values = NULL;
|
||||
float* values = NULL;
|
||||
size_t values_len = 0;
|
||||
size_t i = 0, len = 0;
|
||||
|
||||
double latitudeOfFirstGridPointInDegrees;
|
||||
double longitudeOfFirstGridPointInDegrees;
|
||||
double latitudeOfLastGridPointInDegrees;
|
||||
double longitudeOfLastGridPointInDegrees;
|
||||
|
||||
double jDirectionIncrementInDegrees;
|
||||
double iDirectionIncrementInDegrees;
|
||||
|
||||
long numberOfPointsAlongAParallel;
|
||||
long numberOfPointsAlongAMeridian;
|
||||
|
||||
double average = 0;
|
||||
char* packingType = NULL;
|
||||
|
||||
FILE* in = NULL;
|
||||
const char* filename = "../../data/regular_latlon_surface.grib1";
|
||||
const char* filename = "../../data/sample.grib2";
|
||||
codes_handle* h = NULL;
|
||||
|
||||
in = fopen(filename, "rb");
|
||||
|
@ -58,89 +30,25 @@ int main(int argc, char** argv)
|
|||
}
|
||||
fclose(in);
|
||||
|
||||
/* store the filename in the key "file" for this handle */
|
||||
len = strlen(filename);
|
||||
CODES_CHECK(codes_set_string(h, "file", filename, &len), 0);
|
||||
|
||||
/* get as a long*/
|
||||
CODES_CHECK(codes_get_long(h, "Ni", &numberOfPointsAlongAParallel), 0);
|
||||
printf("numberOfPointsAlongAParallel=%ld\n", numberOfPointsAlongAParallel);
|
||||
|
||||
/* get as a long*/
|
||||
CODES_CHECK(codes_get_long(h, "Nj", &numberOfPointsAlongAMeridian), 0);
|
||||
printf("numberOfPointsAlongAMeridian=%ld\n", numberOfPointsAlongAMeridian);
|
||||
|
||||
/* get as a double*/
|
||||
CODES_CHECK(codes_get_double(h, "latitudeOfFirstGridPointInDegrees", &latitudeOfFirstGridPointInDegrees), 0);
|
||||
printf("latitudeOfFirstGridPointInDegrees=%g\n", latitudeOfFirstGridPointInDegrees);
|
||||
|
||||
/* get as a double*/
|
||||
CODES_CHECK(codes_get_double(h, "longitudeOfFirstGridPointInDegrees", &longitudeOfFirstGridPointInDegrees), 0);
|
||||
printf("longitudeOfFirstGridPointInDegrees=%g\n", longitudeOfFirstGridPointInDegrees);
|
||||
|
||||
/* get as a double*/
|
||||
CODES_CHECK(codes_get_double(h, "latitudeOfLastGridPointInDegrees", &latitudeOfLastGridPointInDegrees), 0);
|
||||
printf("latitudeOfLastGridPointInDegrees=%g\n", latitudeOfLastGridPointInDegrees);
|
||||
|
||||
/* get as a double*/
|
||||
CODES_CHECK(codes_get_double(h, "longitudeOfLastGridPointInDegrees", &longitudeOfLastGridPointInDegrees), 0);
|
||||
printf("longitudeOfLastGridPointInDegrees=%g\n", longitudeOfLastGridPointInDegrees);
|
||||
|
||||
/* get as a double*/
|
||||
CODES_CHECK(codes_get_double(h, "jDirectionIncrementInDegrees", &jDirectionIncrementInDegrees), 0);
|
||||
printf("jDirectionIncrementInDegrees=%g\n", jDirectionIncrementInDegrees);
|
||||
|
||||
/* get as a double*/
|
||||
CODES_CHECK(codes_get_double(h, "iDirectionIncrementInDegrees", &iDirectionIncrementInDegrees), 0);
|
||||
printf("iDirectionIncrementInDegrees=%g\n", iDirectionIncrementInDegrees);
|
||||
|
||||
/* get as string */
|
||||
CODES_CHECK(codes_get_length(h, "packingType", &len), 0);
|
||||
packingType = (char*)malloc(len * sizeof(char));
|
||||
codes_get_string(h, "packingType", packingType, &len);
|
||||
printf("packingType=%s\n", packingType);
|
||||
free(packingType);
|
||||
|
||||
/* get the size of the values array*/
|
||||
CODES_CHECK(codes_get_size(h, "values", &values_len), 0);
|
||||
|
||||
values = (double*)malloc(values_len * sizeof(double));
|
||||
values = (float*)malloc(values_len * sizeof(float));
|
||||
|
||||
/* get data values*/
|
||||
CODES_CHECK(codes_get_double_array(h, "values", values, &values_len), 0);
|
||||
CODES_CHECK(codes_get_float_array(h, "values", values, &values_len), 0);
|
||||
|
||||
average = 0;
|
||||
for (i = 0; i < values_len; i++)
|
||||
for (i = 0; i < values_len; i++){
|
||||
//printf("%f\n",values[i]);
|
||||
average += values[i];
|
||||
}
|
||||
|
||||
average /= (double)values_len;
|
||||
|
||||
free(values);
|
||||
|
||||
printf("There are %d values, average is %g\n", (int)values_len, average);
|
||||
|
||||
{
|
||||
int eq = 0;
|
||||
/* now retrieve the value of the key "file" */
|
||||
char file[256] = {0,};
|
||||
CODES_CHECK(codes_get_length(h, "file", &len), 0);
|
||||
assert(len == 1 + strlen(filename));
|
||||
codes_get_string(h, "file", file, &len);
|
||||
eq = strcmp(file, filename);
|
||||
if (eq != 0) assert(!"file and filename not equal");
|
||||
}
|
||||
|
||||
{
|
||||
/* example of getting bytes */
|
||||
const char* name = "reservedNeedNotBePresent";
|
||||
unsigned char* byte_val = NULL;
|
||||
size_t keySize = 0;
|
||||
CODES_CHECK(codes_get_size(h, name, &keySize), 0);
|
||||
byte_val = (unsigned char*)malloc(keySize * sizeof(unsigned char));
|
||||
GRIB_CHECK(codes_get_bytes(h, name, byte_val, &keySize), name);
|
||||
free(byte_val);
|
||||
}
|
||||
|
||||
codes_handle_delete(h);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1540,6 +1540,7 @@ int grib_encode_size_tb(unsigned char* p, size_t val, long* bitp, long nb);
|
|||
/* grib_bits_any_endian_simple.c */
|
||||
int grib_decode_long_array(const unsigned char* p, long* bitp, long bitsPerValue, size_t n_vals, long* val);
|
||||
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);
|
||||
int grib_decode_float_array(const unsigned char* p, long* bitp, long bitsPerValue, double reference_value, double s, double d, size_t n_vals, float* 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);
|
||||
int grib_encode_long_array(size_t n_vals, const long* val, long bits_per_value, 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);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
CLASS = accessor
|
||||
SUPER = grib_accessor_class_values
|
||||
IMPLEMENTS = init
|
||||
IMPLEMENTS = unpack_double
|
||||
IMPLEMENTS = unpack_double;unpack_float
|
||||
IMPLEMENTS = unpack_double_element;unpack_double_element_set
|
||||
IMPLEMENTS = unpack_double_subarray
|
||||
IMPLEMENTS = pack_double
|
||||
|
@ -54,6 +54,7 @@ or edit "accessor.class" and rerun ./make_class.pl
|
|||
|
||||
static int pack_double(grib_accessor*, const double* val, size_t* len);
|
||||
static int unpack_double(grib_accessor*, double* val, size_t* len);
|
||||
static int unpack_float(grib_accessor*, float* val, size_t* len);
|
||||
static int value_count(grib_accessor*, long*);
|
||||
static void init(grib_accessor*, const long, grib_arguments*);
|
||||
static void init_class(grib_accessor_class*);
|
||||
|
@ -110,7 +111,7 @@ static grib_accessor_class _grib_accessor_class_data_simple_packing = {
|
|||
&pack_double, /* grib_pack procedures double */
|
||||
0, /* grib_pack procedures float */
|
||||
&unpack_double, /* grib_unpack procedures double */
|
||||
0, /* grib_unpack procedures float */
|
||||
&unpack_float, /* grib_unpack procedures float */
|
||||
0, /* grib_pack procedures string */
|
||||
0, /* grib_unpack procedures string */
|
||||
0, /* grib_pack array procedures string */
|
||||
|
@ -150,7 +151,6 @@ static void init_class(grib_accessor_class* c)
|
|||
c->pack_long = (*(c->super))->pack_long;
|
||||
c->unpack_long = (*(c->super))->unpack_long;
|
||||
c->pack_float = (*(c->super))->pack_float;
|
||||
c->unpack_float = (*(c->super))->unpack_float;
|
||||
c->pack_string = (*(c->super))->pack_string;
|
||||
c->unpack_string = (*(c->super))->unpack_string;
|
||||
c->pack_string_array = (*(c->super))->pack_string_array;
|
||||
|
@ -317,6 +317,158 @@ static int unpack_double_element_set(grib_accessor* a, const size_t* index_array
|
|||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
// unpack an array of double or single precision real numbers. As doubles if dval!= NULL or floats if fval!=NULL
|
||||
static int _unpack_real(grib_accessor* a, double* dval, float* fval, size_t* len, unsigned char* buf, long pos, size_t n_vals)
|
||||
{
|
||||
grib_accessor_data_simple_packing* self = (grib_accessor_data_simple_packing*)a;
|
||||
grib_handle* gh = grib_handle_of_accessor(a);
|
||||
|
||||
size_t i = 0;
|
||||
int err = 0;
|
||||
|
||||
double reference_value;
|
||||
long binary_scale_factor;
|
||||
long bits_per_value;
|
||||
long decimal_scale_factor;
|
||||
long offsetBeforeData;
|
||||
double s = 0;
|
||||
double d = 0;
|
||||
double units_factor = 1.0;
|
||||
double units_bias = 0.0;
|
||||
Assert( ! (fval && dval) );
|
||||
printf("DBG:: SIMPLE PACK unpack real.....\n");
|
||||
if (*len < n_vals) {
|
||||
*len = (long)n_vals;
|
||||
return GRIB_ARRAY_TOO_SMALL;
|
||||
}
|
||||
|
||||
if ((err = grib_get_long_internal(gh, self->bits_per_value, &bits_per_value)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* check we don't decode bpv > max(ulong) as it is
|
||||
* not currently supported by the algorithm
|
||||
*/
|
||||
if (bits_per_value > (sizeof(long) * 8)) {
|
||||
return GRIB_INVALID_BPV;
|
||||
}
|
||||
|
||||
if (self->units_factor &&
|
||||
(grib_get_double_internal(gh, self->units_factor, &units_factor) == GRIB_SUCCESS)) {
|
||||
grib_set_double_internal(gh, self->units_factor, 1.0);
|
||||
}
|
||||
|
||||
if (self->units_bias &&
|
||||
(grib_get_double_internal(gh, self->units_bias, &units_bias) == GRIB_SUCCESS)) {
|
||||
grib_set_double_internal(gh, self->units_bias, 0.0);
|
||||
}
|
||||
|
||||
if (n_vals == 0) {
|
||||
*len = 0;
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
self->dirty = 0;
|
||||
|
||||
if ((err = grib_get_double_internal(gh, self->reference_value, &reference_value)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
if ((err = grib_get_long_internal(gh, self->binary_scale_factor, &binary_scale_factor)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
if ((err = grib_get_long_internal(gh, self->decimal_scale_factor, &decimal_scale_factor)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Special case */
|
||||
|
||||
if (bits_per_value == 0) {
|
||||
if (dval) {
|
||||
for (i = 0; i < n_vals; i++)
|
||||
dval[i] = reference_value;
|
||||
} else if (fval) {
|
||||
for (i = 0; i < n_vals; i++)
|
||||
fval[i] = reference_value;
|
||||
}
|
||||
*len = n_vals;
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
s = grib_power(binary_scale_factor, 2);
|
||||
d = grib_power(-decimal_scale_factor, 10);
|
||||
|
||||
grib_context_log(a->context, GRIB_LOG_DEBUG,
|
||||
"grib_accessor_data_simple_packing: unpack_double : creating %s, %d values",
|
||||
a->name, n_vals);
|
||||
|
||||
offsetBeforeData = grib_byte_offset(a);
|
||||
buf += offsetBeforeData;
|
||||
|
||||
/*Assert(((bits_per_value*n_vals)/8) < (1<<29));*/ /* See GRIB-787 */
|
||||
|
||||
/* ECC-941 */
|
||||
if (!a->context->ieee_packing) {
|
||||
/* Must turn off this check when the environment variable ECCODES_GRIB_IEEE_PACKING is on */
|
||||
long offsetAfterData = 0;
|
||||
err = grib_get_long(gh, "offsetAfterData", &offsetAfterData);
|
||||
if (!err && offsetAfterData > offsetBeforeData) {
|
||||
const long valuesSize = (bits_per_value * n_vals) / 8; /*in bytes*/
|
||||
if (offsetBeforeData + valuesSize > offsetAfterData) {
|
||||
grib_context_log(a->context, GRIB_LOG_ERROR,
|
||||
"Data section size mismatch: offset before data=%ld, offset after data=%ld (num values=%ld, bits per value=%ld)",
|
||||
offsetBeforeData, offsetAfterData, n_vals, bits_per_value);
|
||||
return GRIB_DECODING_ERROR;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (offsetBeforeData == offsetAfterData) {
|
||||
/* Crazy case: Constant field with bitsPerValue > 0 */
|
||||
for (i = 0; i < n_vals; i++)
|
||||
val[i] = reference_value;
|
||||
*len = n_vals;
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
grib_context_log(a->context, GRIB_LOG_DEBUG,
|
||||
"unpack_double: calling outline function : bpv %d, rv : %g, sf : %d, dsf : %d ",
|
||||
bits_per_value, reference_value, binary_scale_factor, decimal_scale_factor);
|
||||
if(dval)
|
||||
grib_decode_double_array(buf, &pos, bits_per_value, reference_value, s, d, n_vals, dval);
|
||||
if(fval)
|
||||
grib_decode_float_array(buf, &pos, bits_per_value, reference_value, s, d, n_vals, fval);
|
||||
|
||||
*len = (long)n_vals;
|
||||
|
||||
if(dval) {
|
||||
if (units_factor != 1.0) {
|
||||
if (units_bias != 0.0)
|
||||
for (i = 0; i < n_vals; i++)
|
||||
dval[i] = dval[i] * units_factor + units_bias;
|
||||
else
|
||||
for (i = 0; i < n_vals; i++)
|
||||
dval[i] *= units_factor;
|
||||
}
|
||||
else if (units_bias != 0.0)
|
||||
for (i = 0; i < n_vals; i++)
|
||||
dval[i] += units_bias;
|
||||
}
|
||||
if(fval) {
|
||||
if (units_factor != 1.0) {
|
||||
if (units_bias != 0.0)
|
||||
for (i = 0; i < n_vals; i++)
|
||||
fval[i] = fval[i] * units_factor + units_bias;
|
||||
else
|
||||
for (i = 0; i < n_vals; i++)
|
||||
fval[i] *= units_factor;
|
||||
}
|
||||
else if (units_bias != 0.0)
|
||||
for (i = 0; i < n_vals; i++)
|
||||
fval[i] += units_bias;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int _unpack_double(grib_accessor* a, double* val, size_t* len, unsigned char* buf, long pos, size_t n_vals)
|
||||
{
|
||||
grib_accessor_data_simple_packing* self = (grib_accessor_data_simple_packing*)a;
|
||||
|
@ -464,7 +616,7 @@ static int unpack_double_subarray(grib_accessor* a, double* val, size_t start, s
|
|||
return _unpack_double(a, val, plen, buf, pos, nvals);
|
||||
}
|
||||
|
||||
static int unpack_double(grib_accessor* a, double* val, size_t* len)
|
||||
static int unpack_double(grib_accessor* a, double* dval, size_t* len)
|
||||
{
|
||||
unsigned char* buf = (unsigned char*)grib_handle_of_accessor(a)->buffer->data;
|
||||
size_t nvals = 0;
|
||||
|
@ -476,8 +628,24 @@ static int unpack_double(grib_accessor* a, double* val, size_t* len)
|
|||
if (err)
|
||||
return err;
|
||||
nvals = count;
|
||||
printf("SIMPLE unpak double.....\n");
|
||||
return _unpack_real(a, dval, NULL, len, buf, pos, nvals);
|
||||
}
|
||||
|
||||
return _unpack_double(a, val, len, buf, pos, nvals);
|
||||
static int unpack_float(grib_accessor* a, float* fval, size_t* len)
|
||||
{
|
||||
unsigned char* buf = (unsigned char*)grib_handle_of_accessor(a)->buffer->data;
|
||||
size_t nvals = 0;
|
||||
long pos = 0;
|
||||
int err = 0;
|
||||
long count = 0;
|
||||
|
||||
err = grib_value_count(a, &count);
|
||||
if (err)
|
||||
return err;
|
||||
nvals = count;
|
||||
printf("SIMPLE unpack float.....\n");
|
||||
return _unpack_real(a, NULL, fval, len, buf, pos, nvals);
|
||||
}
|
||||
|
||||
#if GRIB_IBMPOWER67_OPT
|
||||
|
|
|
@ -343,8 +343,10 @@ static int unpack_double(grib_accessor* a, double* v, size_t* len)
|
|||
|
||||
static int unpack_float(grib_accessor* a, float* v, size_t* len)
|
||||
{
|
||||
int type = GRIB_TYPE_UNDEFINED;
|
||||
printf("====%s\n",a->name);
|
||||
/* int type = GRIB_TYPE_UNDEFINED;
|
||||
printf("grib_accessor_class_gen.c unpack_float a->name =%s\n",a->name);
|
||||
printf("grib_accessor_class_gen.c unpack_float a->cclass->name=%s\n",a->cclass->name);
|
||||
printf("grib_accessor_class_gen.c unpack_float alen=%zu\n",*len);
|
||||
printf("DEBUG unpack_float:: a->cclass->unpack_double=%p\n", (void*)a->cclass->unpack_double);
|
||||
printf("DEBUG unpack_float:: &unpack_double=%p\n", (void*)&unpack_double);
|
||||
if (a->cclass->unpack_double && a->cclass->unpack_double != &unpack_double) {
|
||||
|
@ -359,7 +361,7 @@ static int unpack_float(grib_accessor* a, float* v, size_t* len)
|
|||
grib_context_log(a->context, GRIB_LOG_ERROR, "Cannot unpack %s as float", a->name);
|
||||
if (grib_get_native_type(grib_handle_of_accessor(a), a->name, &type) == GRIB_SUCCESS) {
|
||||
grib_context_log(a->context, GRIB_LOG_ERROR, "Hint: Try unpacking as %s", grib_get_type_name(type));
|
||||
}
|
||||
} */
|
||||
|
||||
return GRIB_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
|
@ -164,6 +164,105 @@ int grib_decode_double_array(const unsigned char* p, long* bitp, long bitsPerVal
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: First lame attempt at decoding a float array. This and the grib_decode_double_array function
|
||||
* should be merged and refactored! Most probably using C++ templates
|
||||
*/
|
||||
/**
|
||||
* decode an array of n_vals values from an octet-bitstream to float-representation
|
||||
*
|
||||
* @param p input bitstream, for technical reasons put into octets
|
||||
* @param bitp current position in the bitstream
|
||||
* @param bitsPerValue number of bits needed to build a number (e.g. 8=byte, 16=short, 32=int, but also other sizes allowed)
|
||||
* @param n_vals number of values to decode
|
||||
* @param val output, values encoded as 32/64bit numbers
|
||||
*/
|
||||
int grib_decode_float_array(const unsigned char* p, long* bitp, long bitsPerValue,
|
||||
double reference_value, double s, double d,
|
||||
size_t n_vals, float* val)
|
||||
{
|
||||
long i = 0;
|
||||
unsigned long lvalue = 0;
|
||||
double x;
|
||||
printf("grib_decode_float_array\n");
|
||||
|
||||
#if 0
|
||||
/* slow reference code */
|
||||
int j=0;
|
||||
for(i=0;i < n_vals;i++) {
|
||||
lvalue=0;
|
||||
for(j=0; j< bitsPerValue;j++){
|
||||
lvalue <<= 1;
|
||||
if(grib_get_bit( p, *bitp)) lvalue += 1;
|
||||
*bitp += 1;
|
||||
}
|
||||
x=((lvalue*s)+reference_value)*d;
|
||||
val[i] = (double)x;
|
||||
}
|
||||
#endif
|
||||
if (bitsPerValue % 8 == 0) {
|
||||
/* See ECC-386 */
|
||||
int bc;
|
||||
int l = bitsPerValue / 8;
|
||||
size_t o = 0;
|
||||
|
||||
for (i = 0; i < n_vals; i++) {
|
||||
lvalue = 0;
|
||||
lvalue <<= 8;
|
||||
lvalue |= p[o++];
|
||||
|
||||
for (bc = 1; bc < l; bc++) {
|
||||
lvalue <<= 8;
|
||||
lvalue |= p[o++];
|
||||
}
|
||||
x = ((lvalue * s) + reference_value) * d;
|
||||
val[i] = (float)x;
|
||||
/* *bitp += bitsPerValue * n_vals; */
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned long mask = BIT_MASK1(bitsPerValue);
|
||||
|
||||
/* pi: position of bitp in p[]. >>3 == /8 */
|
||||
long pi = *bitp / 8;
|
||||
/* some bits might of the current byte at pi might be used */
|
||||
/* by the previous number usefulBitsInByte gives remaining unused bits */
|
||||
/* number of useful bits in current byte */
|
||||
int usefulBitsInByte = 8 - (*bitp & 7);
|
||||
for (i = 0; i < n_vals; i++) {
|
||||
/* value read as long */
|
||||
long bitsToRead = 0;
|
||||
lvalue = 0;
|
||||
bitsToRead = bitsPerValue;
|
||||
/* read one byte after the other to lvalue until >= bitsPerValue are read */
|
||||
while (bitsToRead > 0) {
|
||||
lvalue <<= 8;
|
||||
lvalue += p[pi];
|
||||
pi++;
|
||||
bitsToRead -= usefulBitsInByte;
|
||||
usefulBitsInByte = 8;
|
||||
}
|
||||
*bitp += bitsPerValue;
|
||||
/* bitsToRead is now <= 0, remove the last bits */
|
||||
lvalue >>= -1 * bitsToRead;
|
||||
/* set leading bits to 0 - removing bits used for previous number */
|
||||
lvalue &= mask;
|
||||
|
||||
usefulBitsInByte = -1 * bitsToRead; /* prepare for next round */
|
||||
if (usefulBitsInByte > 0) {
|
||||
pi--; /* reread the current byte */
|
||||
}
|
||||
else {
|
||||
usefulBitsInByte = 8; /* start with next full byte */
|
||||
}
|
||||
/* scaling and move value to output */
|
||||
x = ((lvalue * s) + reference_value) * d;
|
||||
val[i] = (float)x;
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
return GRIB_NOT_IMPLEMENTED;
|
||||
|
|
Loading…
Reference in New Issue