diff --git a/src/grib_accessor_class_data_g1second_order_general_extended_packing.c b/src/grib_accessor_class_data_g1second_order_general_extended_packing.c index 610bbd69d..83b794981 100644 --- a/src/grib_accessor_class_data_g1second_order_general_extended_packing.c +++ b/src/grib_accessor_class_data_g1second_order_general_extended_packing.c @@ -205,819 +205,816 @@ static unsigned long nbits[32]={ }; GRIB_INLINE static long number_of_bits(unsigned long x) { - unsigned long *n=nbits; - long i=0; - while (x>=*n) {n++;i++;} - return i; + unsigned long *n=nbits; + long i=0; + while (x>=*n) {n++;i++;} + return i; } static void init(grib_accessor* a,const long v, grib_arguments* args) { - grib_accessor_data_g1second_order_general_extended_packing *self =(grib_accessor_data_g1second_order_general_extended_packing*)a; + grib_accessor_data_g1second_order_general_extended_packing *self =(grib_accessor_data_g1second_order_general_extended_packing*)a; - self->half_byte = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->packingType = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->ieee_packing = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->precision = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->widthOfFirstOrderValues = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->firstOrderValues = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->N1 = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->N2 = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->numberOfGroups = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->codedNumberOfGroups = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->numberOfSecondOrderPackedValues = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->extraValues = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->groupWidths = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->widthOfWidths = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->groupLengths = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->widthOfLengths = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->NL = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->SPD = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->widthOfSPD = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->orderOfSPD = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->numberOfPoints = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->dataFlag = grib_arguments_get_name(a->parent->h,args,self->carg++); - self->edition=1; - self->dirty=1; - self->values=NULL; - self->size=0; - a->flags |= GRIB_ACCESSOR_FLAG_DATA; + self->half_byte = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->packingType = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->ieee_packing = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->precision = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->widthOfFirstOrderValues = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->firstOrderValues = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->N1 = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->N2 = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->numberOfGroups = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->codedNumberOfGroups = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->numberOfSecondOrderPackedValues = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->extraValues = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->groupWidths = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->widthOfWidths = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->groupLengths = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->widthOfLengths = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->NL = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->SPD = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->widthOfSPD = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->orderOfSPD = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->numberOfPoints = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->dataFlag = grib_arguments_get_name(a->parent->h,args,self->carg++); + self->edition=1; + self->dirty=1; + self->values=NULL; + self->size=0; + a->flags |= GRIB_ACCESSOR_FLAG_DATA; } static long value_count(grib_accessor* a) { - grib_accessor_data_g1second_order_general_extended_packing* self = (grib_accessor_data_g1second_order_general_extended_packing*)a; - long numberOfCodedValues=0; - long numberOfGroups=0; - size_t ngroups; - long *groupLengths; - long orderOfSPD=0; - long i; + grib_accessor_data_g1second_order_general_extended_packing* self = (grib_accessor_data_g1second_order_general_extended_packing*)a; + long numberOfCodedValues=0; + long numberOfGroups=0; + size_t ngroups; + long *groupLengths; + long orderOfSPD=0; + long i; - grib_get_long(a->parent->h,self->numberOfGroups,&numberOfGroups); - if (numberOfGroups==0) return 0; + grib_get_long(a->parent->h,self->numberOfGroups,&numberOfGroups); + if (numberOfGroups==0) return 0; - groupLengths=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfGroups); - ngroups=numberOfGroups; - grib_get_long_array(a->parent->h,self->groupLengths,groupLengths,&ngroups); + groupLengths=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfGroups); + ngroups=numberOfGroups; + grib_get_long_array(a->parent->h,self->groupLengths,groupLengths,&ngroups); - for (i=0;iparent->h->context,groupLengths); + grib_context_free(a->parent->h->context,groupLengths); - grib_get_long(a->parent->h,self->orderOfSPD,&orderOfSPD); + grib_get_long(a->parent->h,self->orderOfSPD,&orderOfSPD); - return numberOfCodedValues+orderOfSPD; + return numberOfCodedValues+orderOfSPD; } static int unpack_double(grib_accessor* a, double* values, size_t *len) { - grib_accessor_data_g1second_order_general_extended_packing* self = (grib_accessor_data_g1second_order_general_extended_packing*)a; - int ret=0; - long numberOfGroups,numberOfSecondOrderPackedValues; - long* firstOrderValues=0; - long* X=0; - long pos=0; - unsigned char* buf = (unsigned char*)a->parent->h->buffer->data; - long i,n; - double reference_value; - long binary_scale_factor; - long decimal_scale_factor; - double s,d; - long j,count=0; - long *groupWidths=NULL,*groupLengths=NULL; - long orderOfSPD=0; - long *SPD=0; - long numberOfValues=0; - long bias; - long y=0,z=0,w=0; - size_t k,ngroups; + grib_accessor_data_g1second_order_general_extended_packing* self = (grib_accessor_data_g1second_order_general_extended_packing*)a; + int ret=0; + long numberOfGroups,numberOfSecondOrderPackedValues; + long* firstOrderValues=0; + long* X=0; + long pos=0; + unsigned char* buf = (unsigned char*)a->parent->h->buffer->data; + long i,n; + double reference_value; + long binary_scale_factor; + long decimal_scale_factor; + double s,d; + long j,count=0; + long *groupWidths=NULL,*groupLengths=NULL; + long orderOfSPD=0; + long *SPD=0; + long numberOfValues=0; + long bias=0; + long y=0,z=0,w=0; + size_t k,ngroups; - if (!self->dirty) { - if (*lensize) { - return GRIB_ARRAY_TOO_SMALL; - } - for (k=0;ksize;k++) - values[k]=self->values[k]; + if (!self->dirty) { + if (*lensize) { + return GRIB_ARRAY_TOO_SMALL; + } + for (k=0;ksize;k++) + values[k]=self->values[k]; - *len=self->size; - return GRIB_SUCCESS; - } + *len=self->size; + return GRIB_SUCCESS; + } - self->dirty=0; + self->dirty=0; - buf += grib_byte_offset(a); - numberOfValues=value_count(a); + buf += grib_byte_offset(a); + numberOfValues=value_count(a); - if((ret=grib_get_long_internal(a->parent->h,self->numberOfGroups,&numberOfGroups)) != GRIB_SUCCESS) - return ret; + if((ret=grib_get_long_internal(a->parent->h,self->numberOfGroups,&numberOfGroups)) != GRIB_SUCCESS) + return ret; - if((ret=grib_get_long_internal(a->parent->h,self->binary_scale_factor,&binary_scale_factor)) != GRIB_SUCCESS) - return ret; + if((ret=grib_get_long_internal(a->parent->h,self->binary_scale_factor,&binary_scale_factor)) != GRIB_SUCCESS) + return ret; - ngroups=numberOfGroups; - groupWidths=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfGroups); - ret=grib_get_long_array(a->parent->h,self->groupWidths,groupWidths,&ngroups); - if(ret != GRIB_SUCCESS) return ret; + ngroups=numberOfGroups; + groupWidths=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfGroups); + ret=grib_get_long_array(a->parent->h,self->groupWidths,groupWidths,&ngroups); + if(ret != GRIB_SUCCESS) return ret; - groupLengths=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfGroups); - ret=grib_get_long_array(a->parent->h,self->groupLengths,groupLengths,&ngroups); - if(ret != GRIB_SUCCESS) return ret; + groupLengths=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfGroups); + ret=grib_get_long_array(a->parent->h,self->groupLengths,groupLengths,&ngroups); + if(ret != GRIB_SUCCESS) return ret; - firstOrderValues=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfGroups); - ret=grib_get_long_array(a->parent->h,self->firstOrderValues,firstOrderValues,&ngroups); - if(ret != GRIB_SUCCESS) return ret; + firstOrderValues=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfGroups); + ret=grib_get_long_array(a->parent->h,self->firstOrderValues,firstOrderValues,&ngroups); + if(ret != GRIB_SUCCESS) return ret; - if((ret=grib_get_long_internal(a->parent->h,self->decimal_scale_factor,&decimal_scale_factor)) != GRIB_SUCCESS) - return ret; + if((ret=grib_get_long_internal(a->parent->h,self->decimal_scale_factor,&decimal_scale_factor)) != GRIB_SUCCESS) + return ret; - if((ret=grib_get_double_internal(a->parent->h,self->reference_value,&reference_value)) != GRIB_SUCCESS) - return ret; + if((ret=grib_get_double_internal(a->parent->h,self->reference_value,&reference_value)) != GRIB_SUCCESS) + return ret; - if((ret=grib_get_long_internal(a->parent->h,self->numberOfSecondOrderPackedValues, - &numberOfSecondOrderPackedValues)) != GRIB_SUCCESS) - return ret; + if((ret=grib_get_long_internal(a->parent->h,self->numberOfSecondOrderPackedValues, + &numberOfSecondOrderPackedValues)) != GRIB_SUCCESS) + return ret; - if((ret=grib_get_long_internal(a->parent->h,self->orderOfSPD,&orderOfSPD)) != GRIB_SUCCESS) - return ret; + if((ret=grib_get_long_internal(a->parent->h,self->orderOfSPD,&orderOfSPD)) != GRIB_SUCCESS) + return ret; - if (orderOfSPD) { - size_t nSPD=orderOfSPD+1; - SPD=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*nSPD); - ret=grib_get_long_array(a->parent->h,self->SPD,SPD,&nSPD); - bias=SPD[orderOfSPD]; - if(ret != GRIB_SUCCESS) return ret; - } + if (orderOfSPD) { + size_t nSPD=orderOfSPD+1; + SPD=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*nSPD); + ret=grib_get_long_array(a->parent->h,self->SPD,SPD,&nSPD); + bias=SPD[orderOfSPD]; + if(ret != GRIB_SUCCESS) return ret; + } + X=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfValues); - X=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfValues); + n=orderOfSPD; + for (i=0;i0) { - n=orderOfSPD; - for (i=0;i0) { - - for (j=0;jvalues) { + if (numberOfValues!=self->size) { + grib_context_free(a->parent->h->context,self->values); + self->values=grib_context_malloc_clear(a->parent->h->context,sizeof(double)*numberOfValues); + } + } else { + self->values=grib_context_malloc_clear(a->parent->h->context,sizeof(double)*numberOfValues); + } + s = grib_power(binary_scale_factor,2); + d = grib_power(-decimal_scale_factor,10) ; + for (i=0; ivalues[i]=values[i]; + } - if (self->values) { - if (numberOfValues!=self->size) { - grib_context_free(a->parent->h->context,self->values); - self->values=grib_context_malloc_clear(a->parent->h->context,sizeof(double)*numberOfValues); - } - } else { - self->values=grib_context_malloc_clear(a->parent->h->context,sizeof(double)*numberOfValues); - } + *len=numberOfValues; + self->size=numberOfValues; - s = grib_power(binary_scale_factor,2); - d = grib_power(-decimal_scale_factor,10) ; - for (i=0; ivalues[i]=values[i]; - } + grib_context_free(a->parent->h->context,X); + grib_context_free(a->parent->h->context,groupWidths); + grib_context_free(a->parent->h->context,groupLengths); + grib_context_free(a->parent->h->context,firstOrderValues); + if (orderOfSPD) + grib_context_free(a->parent->h->context,SPD); - *len=numberOfValues; - self->size=numberOfValues; - - grib_context_free(a->parent->h->context,X); - grib_context_free(a->parent->h->context,groupWidths); - grib_context_free(a->parent->h->context,groupLengths); - grib_context_free(a->parent->h->context,firstOrderValues); - if (orderOfSPD) - grib_context_free(a->parent->h->context,SPD); - - return ret; + return ret; } static void grib_split_long_groups(grib_context* c,long* numberOfGroups,long* lengthOfSecondOrderValues, - long* groupLengths,long* widthOfLengths, - long* groupWidths, long widthOfWidths, - long* firstOrderValues,long widthOfFirstOrderValues) { + long* groupLengths,long* widthOfLengths, + long* groupWidths, long widthOfWidths, + long* firstOrderValues,long widthOfFirstOrderValues) { - long i,j; - long newWidth,delta; - long *widthsOfLengths; - long *localWidthsOfLengths; - long *localLengths; - long *localWidths; - long *localFirstOrderValues; - int maxNumberOfGroups=*numberOfGroups*2; + long i,j; + long newWidth,delta; + long *widthsOfLengths; + long *localWidthsOfLengths; + long *localLengths; + long *localWidths; + long *localFirstOrderValues; + int maxNumberOfGroups=*numberOfGroups*2; - /* the widthOfLengths is the same for all the groupLengths and therefore if - few big groups are present all the groups have to be coded with a large number - of bits (big widthOfLengths) even if the majority of them is small. - Here we try to reduce the size of the message splitting the big groups. - */ + /* the widthOfLengths is the same for all the groupLengths and therefore if + few big groups are present all the groups have to be coded with a large number + of bits (big widthOfLengths) even if the majority of them is small. + Here we try to reduce the size of the message splitting the big groups. + */ - widthsOfLengths=grib_context_malloc_clear(c,sizeof(long)*maxNumberOfGroups); - j=0; - /* compute the widthOfLengths and the number of big groups */ - for (i=0;i<*numberOfGroups;i++) { - widthsOfLengths[i]=number_of_bits(groupLengths[i]); - if (*widthOfLengths==widthsOfLengths[i]) { - j++; - } - } + widthsOfLengths=grib_context_malloc_clear(c,sizeof(long)*maxNumberOfGroups); + j=0; + /* compute the widthOfLengths and the number of big groups */ + for (i=0;i<*numberOfGroups;i++) { + widthsOfLengths[i]=number_of_bits(groupLengths[i]); + if (*widthOfLengths==widthsOfLengths[i]) { + j++; + } + } - /* variation of the size of message due to decrease of groupLengths - of 1*/ - newWidth=*widthOfLengths-1; - delta=j*(widthOfWidths+widthOfFirstOrderValues+newWidth)-*numberOfGroups; + /* variation of the size of message due to decrease of groupLengths + of 1*/ + newWidth=*widthOfLengths-1; + delta=j*(widthOfWidths+widthOfFirstOrderValues+newWidth)-*numberOfGroups; - if (delta>=0) { - grib_context_free(c,widthsOfLengths); - return; - } + if (delta>=0) { + grib_context_free(c,widthsOfLengths); + return; + } - localWidthsOfLengths=grib_context_malloc_clear(c,sizeof(long)*maxNumberOfGroups); - localLengths=grib_context_malloc_clear(c,sizeof(long)*maxNumberOfGroups); - localWidths=grib_context_malloc_clear(c,sizeof(long)*maxNumberOfGroups); - localFirstOrderValues=grib_context_malloc_clear(c,sizeof(long)*maxNumberOfGroups); + localWidthsOfLengths=grib_context_malloc_clear(c,sizeof(long)*maxNumberOfGroups); + localLengths=grib_context_malloc_clear(c,sizeof(long)*maxNumberOfGroups); + localWidths=grib_context_malloc_clear(c,sizeof(long)*maxNumberOfGroups); + localFirstOrderValues=grib_context_malloc_clear(c,sizeof(long)*maxNumberOfGroups); - while (newWidth>0) { - /* it is worth to split big groups */ - j=0; - for (i=0;i<*numberOfGroups;i++) { - if (newWidthnewWidth) { - localLengths[j]--; - localWidthsOfLengths[j]--; - j++; - localLengths[j]=1; - localWidthsOfLengths[j]=1; - localWidths[j]=groupWidths[i]; - localFirstOrderValues[j]=firstOrderValues[i]; - } - j++; - } else { - localLengths[j]=groupLengths[i]; - localWidthsOfLengths[j]=widthsOfLengths[i]; - localWidths[j]=groupWidths[i]; - localFirstOrderValues[j]=firstOrderValues[i]; - j++; - } - } + while (newWidth>0) { + /* it is worth to split big groups */ + j=0; + for (i=0;i<*numberOfGroups;i++) { + if (newWidthnewWidth) { + localLengths[j]--; + localWidthsOfLengths[j]--; + j++; + localLengths[j]=1; + localWidthsOfLengths[j]=1; + localWidths[j]=groupWidths[i]; + localFirstOrderValues[j]=firstOrderValues[i]; + } + j++; + } else { + localLengths[j]=groupLengths[i]; + localWidthsOfLengths[j]=widthsOfLengths[i]; + localWidths[j]=groupWidths[i]; + localFirstOrderValues[j]=firstOrderValues[i]; + j++; + } + } - if (j>maxNumberOfGroups) break; + if (j>maxNumberOfGroups) break; - *numberOfGroups=j; - *widthOfLengths=newWidth; - j=0; - *lengthOfSecondOrderValues=0; - for (i=0;i<*numberOfGroups;i++) { - groupLengths[i]=localLengths[i]; - widthsOfLengths[i]=localWidthsOfLengths[i]; - groupWidths[i]=localWidths[i]; - firstOrderValues[i]=localFirstOrderValues[i]; - *lengthOfSecondOrderValues+=groupLengths[i]*groupWidths[i]; - if (*widthOfLengths==widthsOfLengths[i]) j++; - } + *numberOfGroups=j; + *widthOfLengths=newWidth; + j=0; + *lengthOfSecondOrderValues=0; + for (i=0;i<*numberOfGroups;i++) { + groupLengths[i]=localLengths[i]; + widthsOfLengths[i]=localWidthsOfLengths[i]; + groupWidths[i]=localWidths[i]; + firstOrderValues[i]=localFirstOrderValues[i]; + *lengthOfSecondOrderValues+=groupLengths[i]*groupWidths[i]; + if (*widthOfLengths==widthsOfLengths[i]) j++; + } - newWidth--; - delta=j*(widthOfWidths+widthOfFirstOrderValues+newWidth)-*numberOfGroups; - if (delta>=0) break; - } + newWidth--; + delta=j*(widthOfWidths+widthOfFirstOrderValues+newWidth)-*numberOfGroups; + if (delta>=0) break; + } - grib_context_free(c,widthsOfLengths); - grib_context_free(c,localWidthsOfLengths); - grib_context_free(c,localLengths); - grib_context_free(c,localWidths); - grib_context_free(c,localFirstOrderValues); + grib_context_free(c,widthsOfLengths); + grib_context_free(c,localWidthsOfLengths); + grib_context_free(c,localLengths); + grib_context_free(c,localWidths); + grib_context_free(c,localFirstOrderValues); } static int pack_double(grib_accessor* a, const double* val, size_t *len) { - grib_accessor_data_g1second_order_general_extended_packing* self = (grib_accessor_data_g1second_order_general_extended_packing*)a; - int ret=0; - int grib2=0; - long bits_per_value,orderOfSPD,binary_scale_factor; - long numberOfValues; - double max,min; - double decimal,divisor; - double reference_value; - size_t size,sizebits; - long half_byte; - long* X; - long* Xp; - long i; - long incrementGroupLengthA,groupWidthA,prevGroupLength,offsetD,remainingValuesB,groupLengthB; - long maxB,minB,maxAB,minAB; - long offsetBeforeData,offsetSection4; - unsigned char* buffer = NULL; - long maxWidth,maxLength,widthOfWidths,NL,widthOfLengths,N1,N2,extraValues,codedNumberOfGroups,numberOfSecondOrderPackedValues; - long pos; + grib_accessor_data_g1second_order_general_extended_packing* self = (grib_accessor_data_g1second_order_general_extended_packing*)a; + int ret=0; + int grib2=0; + long bits_per_value,orderOfSPD,binary_scale_factor; + long numberOfValues; + double max,min; + double decimal,divisor; + double reference_value; + size_t size,sizebits; + long half_byte; + long* X; + long* Xp; + long i; + long incrementGroupLengthA,groupWidthA,prevGroupLength,offsetD,remainingValuesB,groupLengthB; + long maxB,minB,maxAB,minAB; + long offsetBeforeData,offsetSection4; + unsigned char* buffer = NULL; + long maxWidth,maxLength,widthOfWidths,NL,widthOfLengths,N1,N2,extraValues,codedNumberOfGroups,numberOfSecondOrderPackedValues; + long pos; - long numberOfGroups; - long groupLengthC,groupLengthA,remainingValues,count; - long maxA,minA; - long maxC,minC,offsetC; - long maxAC,minAC; - long range,bias,maxSPD; - long firstOrderValuesMax,offset,groupLength,j,groupWidth,firstOrderValue,lengthOfSecondOrderValues; - long *groupLengths,*groupWidths,*firstOrderValues; - /* long groupLengths[MAX_NUMBER_OF_GROUPS],groupWidths[MAX_NUMBER_OF_GROUPS],firstOrderValues[MAX_NUMBER_OF_GROUPS]; */ + long numberOfGroups; + long groupLengthC,groupLengthA,remainingValues,count; + long maxA,minA; + long maxC,minC,offsetC; + long maxAC,minAC; + long range,bias=0,maxSPD; + long firstOrderValuesMax,offset,groupLength,j,groupWidth,firstOrderValue,lengthOfSecondOrderValues; + long *groupLengths,*groupWidths,*firstOrderValues; + /* long groupLengths[MAX_NUMBER_OF_GROUPS],groupWidths[MAX_NUMBER_OF_GROUPS],firstOrderValues[MAX_NUMBER_OF_GROUPS]; */ - /* TODO put these parameters in def file */ - long startGroupLength=15; - long incrementGroupLength=3; - long minGroupLength=3; - long widthOfSPD,widthOfBias; - long *offsets; - long widthOfFirstOrderValues; - int computeGroupA=1; - long dataHeadersLength,widthsLength,lengthsLength,firstOrderValuesLength; - long decimal_scale_factor; + /* TODO put these parameters in def file */ + long startGroupLength=15; + long incrementGroupLength=3; + long minGroupLength=3; + long widthOfSPD=0,widthOfBias=0; + long *offsets; + long widthOfFirstOrderValues; + int computeGroupA=1; + long dataHeadersLength,widthsLength,lengthsLength,firstOrderValuesLength; + long decimal_scale_factor; - self->dirty=1; + self->dirty=1; - numberOfValues=*len; + numberOfValues=*len; - max = val[0]; - min = max; - for(i=1;i< numberOfValues;i++) { - if (val[i] > max ) max = val[i]; - if (val[i] < min ) min = val[i]; - } + max = val[0]; + min = max; + for(i=1;i< numberOfValues;i++) { + if (val[i] > max ) max = val[i]; + if (val[i] < min ) min = val[i]; + } - /* For constant fields set decimal scale factor to 0 (See GRIB-165) */ - if (min==max) { - grib_set_long_internal(a->parent->h,self->decimal_scale_factor, 0); - } + /* For constant fields set decimal scale factor to 0 (See GRIB-165) */ + if (min==max) { + grib_set_long_internal(a->parent->h,self->decimal_scale_factor, 0); + } - if((ret = grib_get_long_internal(a->parent->h,self->decimal_scale_factor, &decimal_scale_factor)) - != GRIB_SUCCESS) - return ret; - decimal = grib_power(decimal_scale_factor,10); + if((ret = grib_get_long_internal(a->parent->h,self->decimal_scale_factor, &decimal_scale_factor)) + != GRIB_SUCCESS) + return ret; + decimal = grib_power(decimal_scale_factor,10); - max*=decimal; - min*=decimal; + max*=decimal; + min*=decimal; - if (grib_get_nearest_smaller_value(a->parent->h,self->reference_value,min,&reference_value) - !=GRIB_SUCCESS) { + if (grib_get_nearest_smaller_value(a->parent->h,self->reference_value,min,&reference_value) + !=GRIB_SUCCESS) { grib_context_log(a->parent->h->context,GRIB_LOG_ERROR, - "unable to find nearest_smaller_value of %g for %s",min,self->reference_value); + "unable to find nearest_smaller_value of %g for %s",min,self->reference_value); exit(GRIB_INTERNAL_ERROR); } if((ret = grib_set_double_internal(a->parent->h,self->reference_value, reference_value)) != - GRIB_SUCCESS) - return ret; + GRIB_SUCCESS) + return ret; - if((ret=grib_get_long_internal(a->parent->h,self->bits_per_value,&bits_per_value)) != GRIB_SUCCESS) - return ret; + if((ret=grib_get_long_internal(a->parent->h,self->bits_per_value,&bits_per_value)) != GRIB_SUCCESS) + return ret; - if((ret=grib_get_long_internal(a->parent->h,self->offsetdata,&offsetBeforeData)) != GRIB_SUCCESS) - return ret; + if((ret=grib_get_long_internal(a->parent->h,self->offsetdata,&offsetBeforeData)) != GRIB_SUCCESS) + return ret; - if((ret=grib_get_long_internal(a->parent->h,self->offsetsection,&offsetSection4)) != GRIB_SUCCESS) - return ret; + if((ret=grib_get_long_internal(a->parent->h,self->offsetsection,&offsetSection4)) != GRIB_SUCCESS) + return ret; - if((ret=grib_get_long_internal(a->parent->h,self->orderOfSPD,&orderOfSPD)) != GRIB_SUCCESS) - return ret; + if((ret=grib_get_long_internal(a->parent->h,self->orderOfSPD,&orderOfSPD)) != GRIB_SUCCESS) + return ret; - binary_scale_factor = grib_get_binary_scale_fact(max,reference_value,bits_per_value,&ret); + binary_scale_factor = grib_get_binary_scale_fact(max,reference_value,bits_per_value,&ret); - if((ret = grib_set_long_internal(a->parent->h,self->binary_scale_factor, binary_scale_factor)) != - GRIB_SUCCESS) - return ret; + if((ret = grib_set_long_internal(a->parent->h,self->binary_scale_factor, binary_scale_factor)) != + GRIB_SUCCESS) + return ret; - divisor = grib_power(-binary_scale_factor,2); - X=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfValues); + divisor = grib_power(-binary_scale_factor,2); + X=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfValues); for(i=0;i< numberOfValues;i++){ - X[i] = (((val[i]*decimal)-reference_value)*divisor)+0.5; + X[i] = (((val[i]*decimal)-reference_value)*divisor)+0.5; } - groupLengths=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfValues); - groupWidths=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfValues); - firstOrderValues=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfValues); + groupLengths=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfValues); + groupWidths=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfValues); + firstOrderValues=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfValues); - /* spatial differencing */ - switch (orderOfSPD) { - case 1: - for (i=numberOfValues-1;i>0;i--) { - X[i]-=X[i-1]; - } - break; - case 2: - for (i=numberOfValues-1;i>1;i--) { - X[i]-=2*X[i-1]-X[i-2]; - } - break; - case 3: - for (i=numberOfValues-1;i>2;i--) { - X[i]-=3*(X[i-1]-X[i-2])+X[i-3]; - } - break; - } - if (orderOfSPD) { - bias=X[orderOfSPD]; - for (i=orderOfSPD+1;i X[i] ) bias=X[i]; - } - for (i=orderOfSPD;i0;i--) { + X[i]-=X[i-1]; + } + break; + case 2: + for (i=numberOfValues-1;i>1;i--) { + X[i]-=2*X[i-1]-X[i-2]; + } + break; + case 3: + for (i=numberOfValues-1;i>2;i--) { + X[i]-=3*(X[i-1]-X[i-2])+X[i-3]; + } + break; + } + if (orderOfSPD) { + bias=X[orderOfSPD]; + for (i=orderOfSPD+1;i X[i] ) bias=X[i]; + } + for (i=orderOfSPD;iX[count+i]) minA=X[count+i]; - } + count=orderOfSPD; + remainingValues=numberOfValues-count; + numberOfGroups=0; + incrementGroupLengthA=startGroupLength; - } - groupWidthA=number_of_bits(maxA-minA); - range=(long)grib_power(groupWidthA,2)-1; - offsetC=count+groupLengthA; - if (offsetC==numberOfValues) { - /* no more values close group A and end loop */ - groupLengths[numberOfGroups]=groupLengthA; - groupWidths[numberOfGroups]=groupWidthA; - /* firstOrderValues[numberOfGroups]=minA; */ - /* to optimise the width of first order variable */ - firstOrderValues[numberOfGroups] = maxA-range > 0 ? maxA-range : 0; - numberOfGroups++; - break; - } + computeGroupA=1; + while (remainingValues) { + /* group A created with length=incrementGroupLengthA (if enough values remain) + incrementGroupLengthA=startGroupLength always except when coming from an A+C or A+B ok branch + */ + groupLengthA= incrementGroupLengthA < remainingValues ? incrementGroupLengthA : remainingValues ; + if (computeGroupA) { + maxA=X[count]; + minA=X[count]; + for (i=1;iX[count+i]) minA=X[count+i]; + } - /* group C created with length=incrementGroupLength (fixed) - or remaining values if close to end - */ - groupLengthC=incrementGroupLength; - if ( groupLengthC + offsetC > numberOfValues - startGroupLength/2) { - groupLengthC=numberOfValues-offsetC; - } - maxC=X[offsetC]; - minC=X[offsetC]; - for (i=1;iX[offsetC+i]) minC=X[offsetC+i]; - } + } + groupWidthA=number_of_bits(maxA-minA); + range=(long)grib_power(groupWidthA,2)-1; - maxAC= maxA > maxC ? maxA : maxC; - minAC= minA < minC ? minA : minC; + offsetC=count+groupLengthA; + if (offsetC==numberOfValues) { + /* no more values close group A and end loop */ + groupLengths[numberOfGroups]=groupLengthA; + groupWidths[numberOfGroups]=groupWidthA; + /* firstOrderValues[numberOfGroups]=minA; */ + /* to optimise the width of first order variable */ + firstOrderValues[numberOfGroups] = maxA-range > 0 ? maxA-range : 0; + numberOfGroups++; + break; + } - /* check if A+C can be represented with the same width as A*/ - if (maxAC-minAC > range) { - /* A could not be expanded adding C. Check if A could be expanded taking - some elements from preceding group. The condition is always that width of - A doesn't increase. - */ - if (numberOfGroups>0 && groupWidths[numberOfGroups-1] > groupWidthA ) { - prevGroupLength=groupLengths[numberOfGroups-1]-incrementGroupLength; - offsetC=count-incrementGroupLength; - /* preceding group length cannot be less than a minimum value */ - while (prevGroupLength >= minGroupLength) { - maxAC=maxA; - minAC=minA; - for (i=0;iX[offsetC+i]) minAC=X[offsetC+i]; - } + /* group C created with length=incrementGroupLength (fixed) + or remaining values if close to end + */ + groupLengthC=incrementGroupLength; + if ( groupLengthC + offsetC > numberOfValues - startGroupLength/2) { + groupLengthC=numberOfValues-offsetC; + } + maxC=X[offsetC]; + minC=X[offsetC]; + for (i=1;iX[offsetC+i]) minC=X[offsetC+i]; + } - /* no more elements can be transfered, exit loop*/ - if (maxAC-minAC > range) break; + maxAC= maxA > maxC ? maxA : maxC; + minAC= minA < minC ? minA : minC; - maxA=maxAC; - minA=minAC; - groupLengths[numberOfGroups-1]-=incrementGroupLength; - groupLengthA+=incrementGroupLength; - count-=incrementGroupLength; - remainingValues+=incrementGroupLength; - - offsetC-=incrementGroupLength; - prevGroupLength-=incrementGroupLength; - } - } - /* close group A*/ - groupLengths[numberOfGroups]=groupLengthA; - groupWidths[numberOfGroups]=groupWidthA; - /* firstOrderValues[numberOfGroups]=minA; */ - /* to optimise the width of first order variable */ - firstOrderValues[numberOfGroups] = maxA-range > 0 ? maxA-range : 0; - count+=groupLengthA; - remainingValues-=groupLengthA; - numberOfGroups++; - /* incrementGroupLengthA is reset to the fixed startGroupLength as it - could have been changed after the A+C or A+B ok condition. - */ - incrementGroupLengthA=startGroupLength; - computeGroupA=1; + /* check if A+C can be represented with the same width as A*/ + if (maxAC-minAC > range) { + /* A could not be expanded adding C. Check if A could be expanded taking + some elements from preceding group. The condition is always that width of + A doesn't increase. + */ + if (numberOfGroups>0 && groupWidths[numberOfGroups-1] > groupWidthA ) { + prevGroupLength=groupLengths[numberOfGroups-1]-incrementGroupLength; + offsetC=count-incrementGroupLength; + /* preceding group length cannot be less than a minimum value */ + while (prevGroupLength >= minGroupLength) { + maxAC=maxA; + minAC=minA; + for (i=0;iX[offsetC+i]) minAC=X[offsetC+i]; + } + + /* no more elements can be transfered, exit loop*/ + if (maxAC-minAC > range) break; + + maxA=maxAC; + minA=minAC; + groupLengths[numberOfGroups-1]-=incrementGroupLength; + groupLengthA+=incrementGroupLength; + count-=incrementGroupLength; + remainingValues+=incrementGroupLength; + + offsetC-=incrementGroupLength; + prevGroupLength-=incrementGroupLength; + } + } + /* close group A*/ + groupLengths[numberOfGroups]=groupLengthA; + groupWidths[numberOfGroups]=groupWidthA; + /* firstOrderValues[numberOfGroups]=minA; */ + /* to optimise the width of first order variable */ + firstOrderValues[numberOfGroups] = maxA-range > 0 ? maxA-range : 0; + count+=groupLengthA; + remainingValues-=groupLengthA; + numberOfGroups++; + /* incrementGroupLengthA is reset to the fixed startGroupLength as it + could have been changed after the A+C or A+B ok condition. + */ + incrementGroupLengthA=startGroupLength; + computeGroupA=1; #if 0 - if (numberOfGroups==MAX_NUMBER_OF_GROUPS) { - groupLengthA= remainingValues ; - maxA=X[count]; - minA=X[count]; - for (i=1;iX[count+i]) minA=X[count+i]; - } - groupWidthA=number_of_bits(maxA-minA); - range=(long)grib_power(groupWidthA,2)-1; - groupLengths[numberOfGroups]=groupLengthA; - groupWidths[numberOfGroups]=groupWidthA; - firstOrderValues[numberOfGroups] = maxA-range > 0 ? maxA-range : 0; - break; - } + if (numberOfGroups==MAX_NUMBER_OF_GROUPS) { + groupLengthA= remainingValues ; + maxA=X[count]; + minA=X[count]; + for (i=1;iX[count+i]) minA=X[count+i]; + } + groupWidthA=number_of_bits(maxA-minA); + range=(long)grib_power(groupWidthA,2)-1; + groupLengths[numberOfGroups]=groupLengthA; + groupWidths[numberOfGroups]=groupWidthA; + firstOrderValues[numberOfGroups] = maxA-range > 0 ? maxA-range : 0; + break; + } #endif - continue; - } + continue; + } - /* A+C could be coded with the same width as A*/ - offsetD=offsetC+groupLengthC; - if (offsetD==numberOfValues) { - groupLengths[numberOfGroups]=groupLengthA+groupLengthC; - groupWidths[numberOfGroups]=groupWidthA; + /* A+C could be coded with the same width as A*/ + offsetD=offsetC+groupLengthC; + if (offsetD==numberOfValues) { + groupLengths[numberOfGroups]=groupLengthA+groupLengthC; + groupWidths[numberOfGroups]=groupWidthA; - /* range of AC is the same as A*/ - /* firstOrderValues[numberOfGroups]=minAC; */ - /* to optimise the width of first order variable */ - firstOrderValues[numberOfGroups] = maxAC-range > 0 ? maxAC-range : 0; - numberOfGroups++; - break; - } + /* range of AC is the same as A*/ + /* firstOrderValues[numberOfGroups]=minAC; */ + /* to optimise the width of first order variable */ + firstOrderValues[numberOfGroups] = maxAC-range > 0 ? maxAC-range : 0; + numberOfGroups++; + break; + } - /* group B is created with length startGroupLength, starting at the - same offset as C. - */ - remainingValuesB=numberOfValues-offsetC; - groupLengthB= startGroupLength < remainingValuesB ? startGroupLength : remainingValuesB ; - maxB=maxC; - minB=minC; - for (i=groupLengthC;iX[offsetC+i]) minB=X[offsetC+i]; - } + /* group B is created with length startGroupLength, starting at the + same offset as C. + */ + remainingValuesB=numberOfValues-offsetC; + groupLengthB= startGroupLength < remainingValuesB ? startGroupLength : remainingValuesB ; + maxB=maxC; + minB=minC; + for (i=groupLengthC;iX[offsetC+i]) minB=X[offsetC+i]; + } - /* check if group B can be coded with a smaller width than A */ - if (maxB-minB <= range/2 && range>0 ) { + /* check if group B can be coded with a smaller width than A */ + if (maxB-minB <= range/2 && range>0 ) { - /* TODO Add code to try if A can be expanded taking some elements - from the left (preceding) group. - A possible variation is to do this left check (and the previous one) - in the final loop when checking that the width of each group. - */ + /* TODO Add code to try if A can be expanded taking some elements + from the left (preceding) group. + A possible variation is to do this left check (and the previous one) + in the final loop when checking that the width of each group. + */ - /* close group A and continue loop*/ - groupLengths[numberOfGroups]=groupLengthA; - groupWidths[numberOfGroups]=groupWidthA; - /* firstOrderValues[numberOfGroups]=minA; */ - /* to optimise the width of first order variable */ - firstOrderValues[numberOfGroups] = maxA-range > 0 ? maxA-range : 0; - count+=groupLengthA; - remainingValues-=groupLengthA; - numberOfGroups++; + /* close group A and continue loop*/ + groupLengths[numberOfGroups]=groupLengthA; + groupWidths[numberOfGroups]=groupWidthA; + /* firstOrderValues[numberOfGroups]=minA; */ + /* to optimise the width of first order variable */ + firstOrderValues[numberOfGroups] = maxA-range > 0 ? maxA-range : 0; + count+=groupLengthA; + remainingValues-=groupLengthA; + numberOfGroups++; #if 0 - if (numberOfGroups==MAX_NUMBER_OF_GROUPS) { - groupLengthA= remainingValues ; - maxA=X[count]; - minA=X[count]; - for (i=1;iX[count+i]) minA=X[count+i]; - } - groupWidthA=number_of_bits(maxA-minA); - range=(long)grib_power(groupWidthA,2)-1; - groupLengths[numberOfGroups]=groupLengthA; - groupWidths[numberOfGroups]=groupWidthA; - firstOrderValues[numberOfGroups] = maxA-range > 0 ? maxA-range : 0; - break; - } + if (numberOfGroups==MAX_NUMBER_OF_GROUPS) { + groupLengthA= remainingValues ; + maxA=X[count]; + minA=X[count]; + for (i=1;iX[count+i]) minA=X[count+i]; + } + groupWidthA=number_of_bits(maxA-minA); + range=(long)grib_power(groupWidthA,2)-1; + groupLengths[numberOfGroups]=groupLengthA; + groupWidths[numberOfGroups]=groupWidthA; + firstOrderValues[numberOfGroups] = maxA-range > 0 ? maxA-range : 0; + break; + } #endif - incrementGroupLengthA=startGroupLength; - computeGroupA=1; - continue; - } + incrementGroupLengthA=startGroupLength; + computeGroupA=1; + continue; + } - /* check if A+B can be coded with same with as A */ - maxAB= maxA > maxB ? maxA : maxB; - minAB= minA < minB ? minA : minB; - if (maxAB-minAB <= range) { - /* A+B can be merged. The increment used at the beginning of the loop to - build group C is increased to the size of group B - */ - incrementGroupLengthA+=groupLengthB; - maxA=maxAB; - minA=minAB; - computeGroupA=0; - continue; - } + /* check if A+B can be coded with same with as A */ + maxAB= maxA > maxB ? maxA : maxB; + minAB= minA < minB ? minA : minB; + if (maxAB-minAB <= range) { + /* A+B can be merged. The increment used at the beginning of the loop to + build group C is increased to the size of group B + */ + incrementGroupLengthA+=groupLengthB; + maxA=maxAB; + minA=minAB; + computeGroupA=0; + continue; + } - /* A+B cannot be merged, A+C can be merged*/ - incrementGroupLengthA+=groupLengthC; - computeGroupA=1; + /* A+B cannot be merged, A+C can be merged*/ + incrementGroupLengthA+=groupLengthC; + computeGroupA=1; - } /* end of the while*/ + } /* end of the while*/ - /* computing bitsPerValue as the number of bits needed to represent - the firstOrderValues. - */ - max=firstOrderValues[0]; - min=firstOrderValues[0]; - for (i=1;ifirstOrderValues[i]) min=firstOrderValues[i]; - } - widthOfFirstOrderValues=number_of_bits(max-min); - firstOrderValuesMax=(long)grib_power(widthOfFirstOrderValues,2)-1; - - if (numberOfGroups>2) { - /* loop through all the groups except the last in reverse order to - check if each group width is still appropriate for the group. - Focus on groups which have been shrank as left groups of an A group taking - some of their elements. - */ - offsets=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfGroups); - offsets[0]=orderOfSPD; - for (i=1;i=0;i--) { - offset=offsets[i]; - groupLength=groupLengths[i]; + /* computing bitsPerValue as the number of bits needed to represent + the firstOrderValues. + */ + max=firstOrderValues[0]; + min=firstOrderValues[0]; + for (i=1;ifirstOrderValues[i]) min=firstOrderValues[i]; + } + widthOfFirstOrderValues=number_of_bits(max-min); + firstOrderValuesMax=(long)grib_power(widthOfFirstOrderValues,2)-1; - if (groupLength >= startGroupLength) continue; + if (numberOfGroups>2) { + /* loop through all the groups except the last in reverse order to + check if each group width is still appropriate for the group. + Focus on groups which have been shrank as left groups of an A group taking + some of their elements. + */ + offsets=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfGroups); + offsets[0]=orderOfSPD; + for (i=1;i=0;i--) { + offset=offsets[i]; + groupLength=groupLengths[i]; - max=X[offset]; - min=X[offset]; - for (j=1;jX[offset+j]) min=X[offset+j]; - } - groupWidth=number_of_bits(max-min); - range=(long)grib_power(groupWidth,2)-1; + if (groupLength >= startGroupLength) continue; - /* width of first order values has to be unchanged.*/ - for (j=groupWidth;jrange ? max-range : 0; - if (firstOrderValue <= firstOrderValuesMax ) { - groupWidths[i]=j; - firstOrderValues[i]=firstOrderValue; - break; - } - } + max=X[offset]; + min=X[offset]; + for (j=1;jX[offset+j]) min=X[offset+j]; + } + groupWidth=number_of_bits(max-min); + range=(long)grib_power(groupWidth,2)-1; - offsetC=offset; - /* group width of the current group (i) can have been reduced - and it is worth to try to expand the group to get some elements - from the left group if it has bigger width. - */ - if (i>0 && (groupWidths[i-1] > groupWidths[i]) ) { - prevGroupLength=groupLengths[i-1]-incrementGroupLength; - offsetC-=incrementGroupLength; - while (prevGroupLength >= minGroupLength) { - for (j=0;jX[offsetC+j]) min=X[offsetC+j]; - } + /* width of first order values has to be unchanged.*/ + for (j=groupWidth;jrange ? max-range : 0; + if (firstOrderValue <= firstOrderValuesMax ) { + groupWidths[i]=j; + firstOrderValues[i]=firstOrderValue; + break; + } + } - /* width of first order values has to be unchanged*/ - firstOrderValue=max>range ? max-range : 0; - if (max-min > range || firstOrderValue > firstOrderValuesMax ) break; + offsetC=offset; + /* group width of the current group (i) can have been reduced + and it is worth to try to expand the group to get some elements + from the left group if it has bigger width. + */ + if (i>0 && (groupWidths[i-1] > groupWidths[i]) ) { + prevGroupLength=groupLengths[i-1]-incrementGroupLength; + offsetC-=incrementGroupLength; + while (prevGroupLength >= minGroupLength) { + for (j=0;jX[offsetC+j]) min=X[offsetC+j]; + } - groupLengths[i-1]-=incrementGroupLength; - groupLengths[i]+=incrementGroupLength; - firstOrderValues[i]=firstOrderValue; - - offsetC-=incrementGroupLength; - prevGroupLength-=incrementGroupLength; - } - } + /* width of first order values has to be unchanged*/ + firstOrderValue=max>range ? max-range : 0; + if (max-min > range || firstOrderValue > firstOrderValuesMax ) break; - } - grib_context_free(a->parent->h->context,offsets); - } + groupLengths[i-1]-=incrementGroupLength; + groupLengths[i]+=incrementGroupLength; + firstOrderValues[i]=firstOrderValue; - maxWidth=groupWidths[0]; - maxLength=groupLengths[0]; - for (i=1;iparent->h->context,offsets); + } - if (!a->parent->h->context->no_big_group_split) { - grib_split_long_groups(a->parent->h->context,&numberOfGroups,&lengthOfSecondOrderValues, - groupLengths,&widthOfLengths,groupWidths,widthOfWidths, - firstOrderValues,widthOfFirstOrderValues); - } + maxWidth=groupWidths[0]; + maxLength=groupLengths[0]; + for (i=1;iparent->h->context->no_big_group_split) { + grib_split_long_groups(a->parent->h->context,&numberOfGroups,&lengthOfSecondOrderValues, + groupLengths,&widthOfLengths,groupWidths,widthOfWidths, + firstOrderValues,widthOfFirstOrderValues); + } - /* writing SPD */ - if (orderOfSPD) { - if((ret = grib_set_long_internal(a->parent->h,self->widthOfSPD, widthOfSPD)) - != GRIB_SUCCESS) - return ret; - - } + Xp=X+orderOfSPD; + for ( i=0; iparent->h,self->widthOfFirstOrderValues, widthOfFirstOrderValues)) - != GRIB_SUCCESS) - return ret; - - dataHeadersLength=25; + /* writing SPD */ + if (orderOfSPD) { + if((ret = grib_set_long_internal(a->parent->h,self->widthOfSPD, widthOfSPD)) + != GRIB_SUCCESS) + return ret; + + } + + /* end writing SPD */ + + if((ret = grib_set_long_internal(a->parent->h,self->widthOfFirstOrderValues, widthOfFirstOrderValues)) + != GRIB_SUCCESS) + return ret; + + dataHeadersLength=25; if (orderOfSPD) dataHeadersLength+=1+((orderOfSPD+1)*widthOfSPD+7)/8; widthsLength=(widthOfWidths*numberOfGroups+7)/8; lengthsLength=(widthOfLengths*numberOfGroups+7)/8; @@ -1027,131 +1024,128 @@ static int pack_double(grib_accessor* a, const double* val, size_t *len) N1=NL+lengthsLength; N2=N1+firstOrderValuesLength; - NL= NL > 65535 ? 65535 : NL; - N2= N2 > 65535 ? 65535 : N2; - N1= N1 > 65535 ? 65535 : N1; + NL= NL > 65535 ? 65535 : NL; + N2= N2 > 65535 ? 65535 : N2; + N1= N1 > 65535 ? 65535 : N1; - grib_set_long(a->parent->h,self->NL, NL); - grib_set_long(a->parent->h,self->N1, N1); - grib_set_long(a->parent->h,self->N2, N2); - - if (numberOfGroups > 65535 ) { - extraValues=numberOfGroups/65536; - codedNumberOfGroups=numberOfGroups%65536; - } else { - extraValues=0; - codedNumberOfGroups=numberOfGroups; - } + grib_set_long(a->parent->h,self->NL, NL); + grib_set_long(a->parent->h,self->N1, N1); + grib_set_long(a->parent->h,self->N2, N2); - /* if no extraValues key present it is a GRIB2*/ - grib2=0; - if((ret = grib_set_long(a->parent->h,self->extraValues, extraValues)) != GRIB_SUCCESS) { - codedNumberOfGroups=numberOfGroups; - grib2=1; - } + if (numberOfGroups > 65535 ) { + extraValues=numberOfGroups/65536; + codedNumberOfGroups=numberOfGroups%65536; + } else { + extraValues=0; + codedNumberOfGroups=numberOfGroups; + } - if((ret = grib_set_long_internal(a->parent->h,self->codedNumberOfGroups, codedNumberOfGroups)) != GRIB_SUCCESS) - return ret; - - numberOfSecondOrderPackedValues=numberOfValues-orderOfSPD; - if (!grib2 && numberOfSecondOrderPackedValues > 65535 ) - numberOfSecondOrderPackedValues= 65535; + /* if no extraValues key present it is a GRIB2*/ + grib2=0; + if((ret = grib_set_long(a->parent->h,self->extraValues, extraValues)) != GRIB_SUCCESS) { + codedNumberOfGroups=numberOfGroups; + grib2=1; + } - if((ret = grib_set_long_internal(a->parent->h,self->numberOfSecondOrderPackedValues, numberOfSecondOrderPackedValues)) - != GRIB_SUCCESS) - return ret; + if((ret = grib_set_long_internal(a->parent->h,self->codedNumberOfGroups, codedNumberOfGroups)) != GRIB_SUCCESS) + return ret; - if (grib2) { - if((ret = grib_set_long_internal(a->parent->h,self->bits_per_value, bits_per_value)) != GRIB_SUCCESS) - return ret; - } else { - if((ret = grib_set_long_internal(a->parent->h,self->bits_per_value, 0)) != GRIB_SUCCESS) - return ret; - } - - if((ret = grib_set_long_internal(a->parent->h,self->widthOfWidths, widthOfWidths)) != GRIB_SUCCESS) - return ret; - - if((ret = grib_set_long_internal(a->parent->h,self->widthOfLengths, widthOfLengths)) != GRIB_SUCCESS) - return ret; + numberOfSecondOrderPackedValues=numberOfValues-orderOfSPD; + if (!grib2 && numberOfSecondOrderPackedValues > 65535 ) + numberOfSecondOrderPackedValues= 65535; - lengthOfSecondOrderValues=0; - for ( i=0; iparent->h,self->numberOfSecondOrderPackedValues, numberOfSecondOrderPackedValues)) + != GRIB_SUCCESS) + return ret; - size=(lengthOfSecondOrderValues+7)/8; - sizebits=lengthOfSecondOrderValues; + if (grib2) { + if((ret = grib_set_long_internal(a->parent->h,self->bits_per_value, bits_per_value)) != GRIB_SUCCESS) + return ret; + } else { + if((ret = grib_set_long_internal(a->parent->h,self->bits_per_value, 0)) != GRIB_SUCCESS) + return ret; + } - /* padding section 4 to an even number of octets*/ - size = (size+offsetBeforeData-offsetSection4) % 2 ? size+1 : size; - half_byte=8*size-sizebits; - if((ret = grib_set_long_internal(a->parent->h,self->half_byte, half_byte)) != GRIB_SUCCESS) - return ret; + if((ret = grib_set_long_internal(a->parent->h,self->widthOfWidths, widthOfWidths)) != GRIB_SUCCESS) + return ret; - buffer=grib_context_malloc_clear(a->parent->h->context,size); + if((ret = grib_set_long_internal(a->parent->h,self->widthOfLengths, widthOfLengths)) != GRIB_SUCCESS) + return ret; - pos=0; - if (orderOfSPD) { - long SPD[4]={0,}; - size_t nSPD=orderOfSPD+1; - Assert(orderOfSPD<=3); - for (i=0;iparent->h,self->SPD,SPD,nSPD); - if(ret) return ret; - } + lengthOfSecondOrderValues=0; + for ( i=0; iparent->h,self->groupWidths,groupWidths,(size_t)numberOfGroups); - if(ret) return ret; + size=(lengthOfSecondOrderValues+7)/8; + sizebits=lengthOfSecondOrderValues; - ret=grib_set_long_array_internal(a->parent->h,self->groupLengths,groupLengths,(size_t)numberOfGroups); - if(ret) return ret; + /* padding section 4 to an even number of octets*/ + size = (size+offsetBeforeData-offsetSection4) % 2 ? size+1 : size; + half_byte=8*size-sizebits; + if((ret = grib_set_long_internal(a->parent->h,self->half_byte, half_byte)) != GRIB_SUCCESS) + return ret; - ret=grib_set_long_array_internal(a->parent->h,self->firstOrderValues,firstOrderValues,(size_t)numberOfGroups); - if(ret) return ret; + buffer=grib_context_malloc_clear(a->parent->h->context,size); - Xp=X+orderOfSPD; - pos=0; - count=0; - for (i=0;i0) { - for (j=0;jparent->h,self->SPD,SPD,nSPD); + if(ret) return ret; + } + + ret=grib_set_long_array_internal(a->parent->h,self->groupWidths,groupWidths,(size_t)numberOfGroups); + if(ret) return ret; + + ret=grib_set_long_array_internal(a->parent->h,self->groupLengths,groupLengths,(size_t)numberOfGroups); + if(ret) return ret; + + ret=grib_set_long_array_internal(a->parent->h,self->firstOrderValues,firstOrderValues,(size_t)numberOfGroups); + if(ret) return ret; + + Xp=X+orderOfSPD; + pos=0; + count=0; + for (i=0;i0) { + for (j=0;jparent->h->context,buffer); - grib_context_free(a->parent->h->context,X); - grib_context_free(a->parent->h->context,groupLengths); - grib_context_free(a->parent->h->context,groupWidths); - grib_context_free(a->parent->h->context,firstOrderValues); - - return ret; + grib_context_free(a->parent->h->context,buffer); + grib_context_free(a->parent->h->context,X); + grib_context_free(a->parent->h->context,groupLengths); + grib_context_free(a->parent->h->context,groupWidths); + grib_context_free(a->parent->h->context,firstOrderValues); + return ret; } static void destroy(grib_context* context,grib_accessor* a) { - grib_accessor_data_g1second_order_general_extended_packing *self =(grib_accessor_data_g1second_order_general_extended_packing*)a; + grib_accessor_data_g1second_order_general_extended_packing *self =(grib_accessor_data_g1second_order_general_extended_packing*)a; if (self->values != NULL) { grib_context_free(context, self->values); self->values=NULL; } } - diff --git a/tools/grib_get.c b/tools/grib_get.c index f1ae12934..74307b2a1 100644 --- a/tools/grib_get.c +++ b/tools/grib_get.c @@ -40,8 +40,8 @@ grib_option grib_options[]={ }; char* grib_tool_description="Get values of some keys from a grib file." - "\n\tIt is similar to grib_ls, but fails returning an error code " - "\n\twhen an error occurs (e.g. key not found)."; + "\n\tIt is similar to grib_ls, but fails returning an error code " + "\n\twhen an error occurs (e.g. key not found)."; char* grib_tool_name="grib_get"; char* grib_tool_usage="[options] grib_file grib_file ..."; @@ -55,163 +55,163 @@ int main(int argc, char *argv[]) { return grib_tool(argc,argv);} int grib_tool_before_getopt(grib_runtime_options* options) { - options->print_keys_count=-1; - return 0; + options->print_keys_count=-1; + return 0; } int grib_tool_init(grib_runtime_options* options) { - char *theEnd = NULL, *end1=NULL; - size_t size=4; - int ret=0; - double min=0,max=0; - int i=0,idx=0; - char* p=NULL; - - options->print_header=0; - options->print_statistics=0; - options->default_print_width=-1; + char *theEnd = NULL, *end1=NULL; + size_t size=4; + int ret=0; + double min=0,max=0; + int i=0; + char* p=NULL; - if (options->latlon) { + options->print_header=0; + options->print_statistics=0; + options->default_print_width=-1; - lat = strtod(options->latlon,&theEnd); - if (*theEnd != ',') { - printf("ERROR: wrong latitude value\n"); - exit(1); - } - lon= strtod(++theEnd,&end1); - - mode=GRIB_NEAREST_SAME_POINT | GRIB_NEAREST_SAME_GRID; + if (options->latlon) { - if (end1 && *end1 == ',') { - end1++; - if (*end1 != '0') { - p=end1; - while (*p != ',' && *p !='\0') p++; - if (*end1 == '4') { - options->latlon_mode=4; - } else if (*end1 == '1') { - options->latlon_mode=1; - } else { - printf("ERROR %s: wrong mode given in option -l\n",grib_tool_name); - exit(1); + lat = strtod(options->latlon,&theEnd); + if (*theEnd != ',') { + printf("ERROR: wrong latitude value\n"); + exit(1); } - } - if (*p == ',') { - p++; - options->latlon_mask=strdup(p); - } + lon= strtod(++theEnd,&end1); + + mode=GRIB_NEAREST_SAME_POINT | GRIB_NEAREST_SAME_GRID; + + if (end1 && *end1 == ',') { + end1++; + if (*end1 != '0') { + p=end1; + while (*p != ',' && *p !='\0') p++; + if (*end1 == '4') { + options->latlon_mode=4; + } else if (*end1 == '1') { + options->latlon_mode=1; + } else { + printf("ERROR %s: wrong mode given in option -l\n",grib_tool_name); + exit(1); + } + } + if (*p == ',') { + p++; + options->latlon_mask=strdup(p); + } + } + + } + if (options->latlon && options->latlon_mask) { + FILE* f=NULL; + grib_handle* hh; + f=fopen(options->latlon_mask,"r"); + if(!f) { + perror(options->latlon_mask); + exit(1); + } + hh=grib_handle_new_from_file(0,f,&ret); + fclose(f); + GRIB_CHECK_NOLINE(ret,0); + n=grib_nearest_new(hh,&ret); + GRIB_CHECK_NOLINE(ret,0); + GRIB_CHECK_NOLINE(grib_nearest_find(n,hh,lat,lon,mode, + options->lats,options->lons,options->mask_values,options->distances,options->indexes,&size),0); + grib_nearest_delete(n); + n=NULL; + grib_handle_delete( hh); - } + options->latlon_idx=-1; + max=options->distances[0]; + for (i=0;i<4;i++) + if (maxdistances[i]) {max=options->distances[i];} + min=max; + for (i=0;i<4;i++) { + if ((min >= options->distances[i]) && (options->mask_values[i] >= 0.5)) { + options->latlon_idx=i; + min = options->distances[i]; + } + } - if (options->latlon && options->latlon_mask) { - FILE* f=NULL; - grib_handle* hh; - f=fopen(options->latlon_mask,"r"); - if(!f) { - perror(options->latlon_mask); - exit(1); - } - hh=grib_handle_new_from_file(0,f,&ret); - fclose(f); - GRIB_CHECK_NOLINE(ret,0); - n=grib_nearest_new(hh,&ret); - GRIB_CHECK_NOLINE(ret,0); - GRIB_CHECK_NOLINE(grib_nearest_find(n,hh,lat,lon,mode, - options->lats,options->lons,options->mask_values,options->distances,options->indexes,&size),0); - grib_nearest_delete(n); - n=NULL; - grib_handle_delete( hh); - - options->latlon_idx=-1; - max=options->distances[0]; - for (i=0;i<4;i++) - if (maxdistances[i]) {max=options->distances[i];idx=i;} - min=max; - for (i=0;i<4;i++) { - if ((min >= options->distances[i]) && (options->mask_values[i] >= 0.5)) { - options->latlon_idx=i; - min = options->distances[i]; - } - } - - if (options->latlon_idx<0){ - min=0; - options->latlon_idx=0; - for (i=1;i<4;i++) - if (min>options->distances[i]) { - min = options->distances[i]; - options->latlon_idx=i; + if (options->latlon_idx<0){ + min=0; + options->latlon_idx=0; + for (i=1;i<4;i++) + if (min>options->distances[i]) { + min = options->distances[i]; + options->latlon_idx=i; + } } } - } - - return 0; + + return 0; } int grib_tool_new_filename_action(grib_runtime_options* options,const char* file) { - return 0; - } + return 0; +} int grib_tool_new_file_action(grib_runtime_options* options,grib_tools_file* file) { - return 0; + return 0; } int grib_tool_new_handle_action(grib_runtime_options* options,grib_handle* h) { - size_t size=4; - int err = 0; + size_t size=4; + int err = 0; - if (!options->skip) { - if (options->set_values_count != 0) { - err=grib_set_values(h,options->set_values,options->set_values_count); + if (!options->skip) { + if (options->set_values_count != 0) { + err=grib_set_values(h,options->set_values,options->set_values_count); + } + + if (err != GRIB_SUCCESS && options->fail) exit(err); } - if (err != GRIB_SUCCESS && options->fail) exit(err); - } + if (options->latlon) { + int err=0; + double min; + int i; + if (!n) n=grib_nearest_new(h,&err); + GRIB_CHECK_NOLINE(err,0); + GRIB_CHECK_NOLINE(grib_nearest_find(n,h,lat,lon,mode, + options->lats,options->lons,options->values, + options->distances,options->indexes,&size),0); + min=options->distances[0]; + options->latlon_idx=0; + i=0; + for (i=1;i<4;i++) { + if (min>options->distances[i]) { + min=options->distances[i]; + options->latlon_idx=i; + } + } + } - if (options->latlon) { - int err=0; - double min; - int i; - if (!n) n=grib_nearest_new(h,&err); - GRIB_CHECK_NOLINE(err,0); - GRIB_CHECK_NOLINE(grib_nearest_find(n,h,lat,lon,mode, - options->lats,options->lons,options->values, - options->distances,options->indexes,&size),0); - min=options->distances[0]; - options->latlon_idx=0; - i=0; - for (i=1;i<4;i++) { - if (min>options->distances[i]) { - min=options->distances[i]; - options->latlon_idx=i; - } - } - } - - return 0; + return 0; } int grib_tool_skip_handle(grib_runtime_options* options, grib_handle* h) { - grib_handle_delete(h); - return 0; + grib_handle_delete(h); + return 0; } void grib_tool_print_key_values(grib_runtime_options* options,grib_handle* h) { - grib_print_key_values(options,h); + grib_print_key_values(options,h); } int grib_tool_finalise_action(grib_runtime_options* options) { - if (n) grib_nearest_delete(n); - - return 0; + if (n) grib_nearest_delete(n); + + return 0; } diff --git a/tools/grib_ls.c b/tools/grib_ls.c index b3f439209..073386b00 100644 --- a/tools/grib_ls.c +++ b/tools/grib_ls.c @@ -43,7 +43,7 @@ grib_option grib_options[]={ }; char* grib_tool_description="List content of grib files printing values of " - "some keys.\n\tIt does not fail when a key is not found."; + "some keys.\n\tIt does not fail when a key is not found."; char* grib_tool_name="grib_ls"; char* grib_tool_usage="[options] grib_file grib_file ..."; static char* new_handle=""; @@ -63,159 +63,159 @@ int main(int argc, char *argv[]) { return grib_tool(argc,argv);} This is executed before processing the options with i getopt and therfore it is the right place for hacking the arguments if needed -*/ + */ int grib_tool_before_getopt(grib_runtime_options* options) { - return 0; + return 0; } /* The options have been parsed and the structure grib_runtime_options* options has been loaded. Initialization and startup can be done here -*/ + */ int grib_tool_init(grib_runtime_options* options) { - char *theEnd = NULL, *end1=NULL; - size_t size=4; - int ret=0; - double min=0,max=0; - int i=0,idx=0; - char* p=NULL; - if (grib_options_on("j")) { - options->verbose=0; - json=1; - } + char *theEnd = NULL, *end1=NULL; + size_t size=4; + int ret=0; + double min=0,max=0; + int i=0; + char* p=NULL; + if (grib_options_on("j")) { + options->verbose=0; + json=1; + } - if (options->latlon) { + if (options->latlon) { - lat = strtod(options->latlon,&theEnd); - if (*theEnd != ',') { - printf("ERROR: wrong latitude value\n"); - exit(1); - } - lon= strtod(++theEnd,&end1); + lat = strtod(options->latlon,&theEnd); + if (*theEnd != ',') { + printf("ERROR: wrong latitude value\n"); + exit(1); + } + lon= strtod(++theEnd,&end1); - mode=GRIB_NEAREST_SAME_POINT | GRIB_NEAREST_SAME_GRID; + mode=GRIB_NEAREST_SAME_POINT | GRIB_NEAREST_SAME_GRID; - if (end1 && *end1 == ',') { - end1++; - if (*end1 != '0') { - p=end1; - while (*p != ',' && *p !='\0') p++; - if (*end1 == '4') { - options->latlon_mode=4; - } else if (*end1 == '1') { - options->latlon_mode=1; - } else { - printf("ERROR %s: wrong mode given in option -l\n",grib_tool_name); - exit(1); - } - } - if (*p == ',') { - p++; - options->latlon_mask=strdup(p); - } - } + if (end1 && *end1 == ',') { + end1++; + if (*end1 != '0') { + p=end1; + while (*p != ',' && *p !='\0') p++; + if (*end1 == '4') { + options->latlon_mode=4; + } else if (*end1 == '1') { + options->latlon_mode=1; + } else { + printf("ERROR %s: wrong mode given in option -l\n",grib_tool_name); + exit(1); + } + } + if (*p == ',') { + p++; + options->latlon_mask=strdup(p); + } + } - } + } - if (options->latlon && options->latlon_mask) { - FILE* f=NULL; - grib_handle* hh; - f=fopen(options->latlon_mask,"r"); - if(!f) { - perror(options->latlon_mask); - exit(1); - } - hh=grib_handle_new_from_file(0,f,&ret); - fclose(f); - GRIB_CHECK_NOLINE(ret,0); - n=grib_nearest_new(hh,&ret); - GRIB_CHECK_NOLINE(ret,0); - GRIB_CHECK_NOLINE(grib_nearest_find(n,hh,lat,lon,mode, - options->lats,options->lons,options->mask_values,options->distances,options->indexes,&size),0); - grib_nearest_delete(n); - n=NULL; - grib_handle_delete( hh); + if (options->latlon && options->latlon_mask) { + FILE* f=NULL; + grib_handle* hh; + f=fopen(options->latlon_mask,"r"); + if(!f) { + perror(options->latlon_mask); + exit(1); + } + hh=grib_handle_new_from_file(0,f,&ret); + fclose(f); + GRIB_CHECK_NOLINE(ret,0); + n=grib_nearest_new(hh,&ret); + GRIB_CHECK_NOLINE(ret,0); + GRIB_CHECK_NOLINE(grib_nearest_find(n,hh,lat,lon,mode, + options->lats,options->lons,options->mask_values,options->distances,options->indexes,&size),0); + grib_nearest_delete(n); + n=NULL; + grib_handle_delete( hh); - options->latlon_idx=-1; - max=options->distances[0]; - for (i=0;i<4;i++) - if (maxdistances[i]) {max=options->distances[i];idx=i;} - min=max; - for (i=0;i<4;i++) { - if ((min >= options->distances[i]) && (options->mask_values[i] >= 0.5)) { - options->latlon_idx=i; - min = options->distances[i]; - } - } + options->latlon_idx=-1; + max=options->distances[0]; + for (i=0;i<4;i++) + if (maxdistances[i]) {max=options->distances[i];} + min=max; + for (i=0;i<4;i++) { + if ((min >= options->distances[i]) && (options->mask_values[i] >= 0.5)) { + options->latlon_idx=i; + min = options->distances[i]; + } + } - if (options->latlon_idx<0){ - min=0; - options->latlon_idx=0; - for (i=1;i<4;i++) - if (min>options->distances[i]) { - min = options->distances[i]; - options->latlon_idx=i; - } - } - } - if (json) printf("[\n"); + if (options->latlon_idx<0){ + min=0; + options->latlon_idx=0; + for (i=1;i<4;i++) + if (min>options->distances[i]) { + min = options->distances[i]; + options->latlon_idx=i; + } + } + } + if (json) printf("[\n"); - return 0; + return 0; } /* A new file is being parsed. The file name is file. This function is called every time a new input file name is processed, before opening the file. -*/ + */ int grib_tool_new_filename_action(grib_runtime_options* options,const char* file) { - return 0; + return 0; } int grib_tool_new_file_action(grib_runtime_options* options,grib_tools_file* file) { - return 0; + return 0; } static void print_key_values(grib_runtime_options* options,grib_handle* h) { - int i; - int ret=0; - char* s="\"keys\" : {"; - double dvalue=0; - long lvalue=0; - char value[MAX_STRING_LEN]; - size_t len=MAX_STRING_LEN; - for (i=0;iprint_keys_count;i++) { - ret=GRIB_SUCCESS; - printf("%s",s); - len=MAX_STRING_LEN; - printf("\"%s\" : ",options->print_keys[i].name); - if (grib_is_missing(h,options->print_keys[i].name,&ret) && ret==GRIB_SUCCESS) - printf("\"missing\""); - else if ( ret == GRIB_SUCCESS ) { - if (options->print_keys[i].type == GRIB_TYPE_UNDEFINED) - grib_get_native_type(h,options->print_keys[i].name,&(options->print_keys[i].type)); - switch (options->print_keys[i].type) { - case GRIB_TYPE_STRING: - ret=grib_get_string( h,options->print_keys[i].name,value,&len); - printf("\"%s\"",value); - break; - case GRIB_TYPE_DOUBLE: - ret=grib_get_double( h,options->print_keys[i].name,&dvalue); - printf("%g",dvalue); - break; - case GRIB_TYPE_LONG: - ret=grib_get_long( h,options->print_keys[i].name,&lvalue); - printf("%ld",lvalue); - break; - default: - printf("invalid_type"); - } - } - if (ret == GRIB_NOT_FOUND) printf("null"); - s=", "; - } - printf("}"); + int i; + int ret=0; + char* s="\"keys\" : {"; + double dvalue=0; + long lvalue=0; + char value[MAX_STRING_LEN]; + size_t len=MAX_STRING_LEN; + for (i=0;iprint_keys_count;i++) { + ret=GRIB_SUCCESS; + printf("%s",s); + len=MAX_STRING_LEN; + printf("\"%s\" : ",options->print_keys[i].name); + if (grib_is_missing(h,options->print_keys[i].name,&ret) && ret==GRIB_SUCCESS) + printf("\"missing\""); + else if ( ret == GRIB_SUCCESS ) { + if (options->print_keys[i].type == GRIB_TYPE_UNDEFINED) + grib_get_native_type(h,options->print_keys[i].name,&(options->print_keys[i].type)); + switch (options->print_keys[i].type) { + case GRIB_TYPE_STRING: + ret=grib_get_string( h,options->print_keys[i].name,value,&len); + printf("\"%s\"",value); + break; + case GRIB_TYPE_DOUBLE: + ret=grib_get_double( h,options->print_keys[i].name,&dvalue); + printf("%g",dvalue); + break; + case GRIB_TYPE_LONG: + ret=grib_get_long( h,options->print_keys[i].name,&lvalue); + printf("%ld",lvalue); + break; + default: + printf("invalid_type"); + } + } + if (ret == GRIB_NOT_FOUND) printf("null"); + s=", "; + } + printf("}"); } /* A new handle is available from the current input file and can be processed here. @@ -223,125 +223,125 @@ The handle available in this function is in the set of messages satisfying the c -w option. They are not to be skipped. */ int grib_tool_new_handle_action(grib_runtime_options* options, grib_handle* h) { - size_t size=4; - double v=0; - int err=0; - int i; + size_t size=4; + double v=0; + int err=0; + int i; - if (!options->skip) { + if (!options->skip) { - if (options->set_values_count != 0) - err=grib_set_values(h,options->set_values,options->set_values_count); + if (options->set_values_count != 0) + err=grib_set_values(h,options->set_values,options->set_values_count); - if( err != GRIB_SUCCESS && options->fail) exit(err); - } + if( err != GRIB_SUCCESS && options->fail) exit(err); + } - if (options->latlon) { - int err=0; - double min; - if (!n) n=grib_nearest_new(h,&err); - GRIB_CHECK_NOLINE(err,0); - GRIB_CHECK_NOLINE(grib_nearest_find(n,h,lat,lon,0, - options->lats,options->lons,options->values, - options->distances,options->indexes,&size),0); + if (options->latlon) { + int err=0; + double min; + if (!n) n=grib_nearest_new(h,&err); + GRIB_CHECK_NOLINE(err,0); + GRIB_CHECK_NOLINE(grib_nearest_find(n,h,lat,lon,0, + options->lats,options->lons,options->values, + options->distances,options->indexes,&size),0); - if (!options->latlon_mask) { - min=options->distances[0]; - options->latlon_idx=0; - i=0; - for (i=1;i<4;i++) { - if (min>options->distances[i]) { - min=options->distances[i]; - options->latlon_idx=i; - } - } - } + if (!options->latlon_mask) { + min=options->distances[0]; + options->latlon_idx=0; + i=0; + for (i=1;i<4;i++) { + if (min>options->distances[i]) { + min=options->distances[i]; + options->latlon_idx=i; + } + } + } - if (json) { - char* s="\n[\n"; - double missingValue=9999; - char value[MAX_STRING_LEN]; - size_t len=MAX_STRING_LEN; - printf("%s",new_handle); - printf( "{\n"); - print_key_values(options,h); - printf("\n, \"selected\" : %d",options->latlon_idx); - printf(", \"method\" : "); - if (options->latlon_mask) printf("\"nearest_land\""); - else printf("\"nearest\""); - printf("\n, \"neighbours\" : "); - for (i=0;i<4;i++) { - printf("%s",s); - len=MAX_STRING_LEN; - printf("{\"index\" : %d, \"latitude\" : %g, \"longitude\" : %g, \"distance\" : %g, " - "\"distance_unit\" : \"km\", ", - (int)options->indexes[i],options->lats[i],options->lons[i], - options->distances[i]); - if (grib_get_double_element(h,"values",options->indexes[i],&v) == GRIB_SUCCESS) { - if (v==missingValue) printf("\"value\" : null "); - else printf("\"value\" : %g ",v); - } + if (json) { + char* s="\n[\n"; + double missingValue=9999; + char value[MAX_STRING_LEN]; + size_t len=MAX_STRING_LEN; + printf("%s",new_handle); + printf( "{\n"); + print_key_values(options,h); + printf("\n, \"selected\" : %d",options->latlon_idx); + printf(", \"method\" : "); + if (options->latlon_mask) printf("\"nearest_land\""); + else printf("\"nearest\""); + printf("\n, \"neighbours\" : "); + for (i=0;i<4;i++) { + printf("%s",s); + len=MAX_STRING_LEN; + printf("{\"index\" : %d, \"latitude\" : %g, \"longitude\" : %g, \"distance\" : %g, " + "\"distance_unit\" : \"km\", ", + (int)options->indexes[i],options->lats[i],options->lons[i], + options->distances[i]); + if (grib_get_double_element(h,"values",options->indexes[i],&v) == GRIB_SUCCESS) { + if (v==missingValue) printf("\"value\" : null "); + else printf("\"value\" : %g ",v); + } - if (grib_get_string( h,"units",value,&len)==GRIB_SUCCESS) - printf(", \"unit\" : \"%s\"",value); + if (grib_get_string( h,"units",value,&len)==GRIB_SUCCESS) + printf(", \"unit\" : \"%s\"",value); - if (options->latlon_mask) - printf(", \"mask_value\"=%.2f",options->mask_values[i]); - printf("}"); - s="\n,"; - } + if (options->latlon_mask) + printf(", \"mask_value\"=%.2f",options->mask_values[i]); + printf("}"); + s="\n,"; + } - printf("\n]"); - printf("\n}"); - } - } - new_handle="\n,"; - return 0; + printf("\n]"); + printf("\n}"); + } + } + new_handle="\n,"; + return 0; } /* A new handle to skip is available. At this point something can be done with the message to be skipped before deleting the handle. */ int grib_tool_skip_handle(grib_runtime_options* options, grib_handle* h) { - grib_handle_delete(h); - return 0; + grib_handle_delete(h); + return 0; } /* key values can be printed in this function. Headers are already printed if requested.*/ void grib_tool_print_key_values(grib_runtime_options* options,grib_handle* h) { - grib_print_key_values(options,h); + grib_print_key_values(options,h); } /* this is executed after the last message in the last file is processed */ int grib_tool_finalise_action(grib_runtime_options* options) { - int i=0; - if (options->latlon && options->verbose) { + int i=0; + if (options->latlon && options->verbose) { - printf("Input Point: latitude=%.2f longitude=%.2f\n",lat,lon); - printf("Grid Point chosen #%d index=%d latitude=%.2f longitude=%.2f distance=%.2f (Km)\n", - options->latlon_idx+1,(int)options->indexes[options->latlon_idx], - options->lats[options->latlon_idx], - options->lons[options->latlon_idx], - options->distances[options->latlon_idx]); + printf("Input Point: latitude=%.2f longitude=%.2f\n",lat,lon); + printf("Grid Point chosen #%d index=%d latitude=%.2f longitude=%.2f distance=%.2f (Km)\n", + options->latlon_idx+1,(int)options->indexes[options->latlon_idx], + options->lats[options->latlon_idx], + options->lons[options->latlon_idx], + options->distances[options->latlon_idx]); - if (options->latlon_mask) { - printf("Mask values:\n"); - for (i=0;i<4;i++) { - printf("- %d - index=%d latitude=%.2f longitude=%.2f distance=%.2f (Km) value=%.2f\n", - i+1,(int)options->indexes[i],options->lats[i],options->lons[i], - options->distances[i],options->mask_values[i]); - } - } else { - printf("Other grid Points\n"); - for (i=0;i<4;i++) { - printf("- %d - index=%d latitude=%.2f longitude=%.2f distance=%.2f (Km)\n", - i+1,(int)options->indexes[i],options->lats[i],options->lons[i], - options->distances[i]); - } - } - } + if (options->latlon_mask) { + printf("Mask values:\n"); + for (i=0;i<4;i++) { + printf("- %d - index=%d latitude=%.2f longitude=%.2f distance=%.2f (Km) value=%.2f\n", + i+1,(int)options->indexes[i],options->lats[i],options->lons[i], + options->distances[i],options->mask_values[i]); + } + } else { + printf("Other grid Points\n"); + for (i=0;i<4;i++) { + printf("- %d - index=%d latitude=%.2f longitude=%.2f distance=%.2f (Km)\n", + i+1,(int)options->indexes[i],options->lats[i],options->lons[i], + options->distances[i]); + } + } + } - if (n) grib_nearest_delete(n); - if (json) printf("\n]\n"); + if (n) grib_nearest_delete(n); + if (json) printf("\n]\n"); - return 0; + return 0; }