int grib_encode_unsigned_long(unsigned char* p, unsigned long val ,long *bitp, long nbits) { long len = nbits; int s = *bitp%8; int n = 8-s; unsigned char tmp = 0; /*for temporary results*/ if(nbits > max_nbits) { /* TODO: Do some real code here, to support long longs */ int bits = nbits; int mod = bits % max_nbits; long zero = 0; /* printf("Warning: encoding %ld bits=%ld %ld\n",val,nbits,*bitp); */ if(mod != 0) { int e=grib_encode_unsigned_long(p,zero,bitp,mod); /* printf(" -> : encoding %ld bits=%ld %ld\n",zero,(long)mod,*bitp); */ Assert( e == 0); bits -= mod; } while(bits > max_nbits) { int e=grib_encode_unsigned_long(p,zero,bitp,max_nbits); /* printf(" -> : encoding %ld bits=%ld %ld\n",zero,(long)max_nbits,*bitp); */ Assert(e == 0); bits -= max_nbits; } /* printf(" -> : encoding %ld bits=%ld %ld\n",val,(long)bits,*bitp); */ return grib_encode_unsigned_long(p,val,bitp,bits); } if(s) p += (*bitp >> 3); /* skip the bytes */ else
static int pack_double (grib_accessor* a, const double* val, size_t *len) { grib_accessor_ibmfloat* self = (grib_accessor_ibmfloat*)a; int ret = 0; unsigned long i = 0; unsigned long rlen = *len; size_t buflen = 0; unsigned char *buf = NULL; long off = 0; if(*len < 1) { grib_context_log(a->parent->h->context, GRIB_LOG_ERROR, " wrong size for %s it pack at least 1 values ", a->name , rlen ); *len = 0; return GRIB_ARRAY_TOO_SMALL; } if (rlen == 1){ /* double x = 0; grib_nearest_smaller_ibm_float(val[0],&x); double y = grib_long_to_ibm(grib_ibm_to_long(val[0])); printf("IBMFLOAT val=%.20f nearest_smaller_ibm_float=%.20f long_to_ibm=%.20f\n",val[0],x ,y); */ off = byte_offset(a)*8; ret = grib_encode_unsigned_long(a->parent->h->buffer->data,grib_ibm_to_long(val[0]), &off, 32); if (*len > 1) grib_context_log(a->parent->h->context, GRIB_LOG_WARNING, "grib_accessor_unsigned : Trying to pack %d values in a scalar %s, packing first value", *len, a->name ); if (ret == GRIB_SUCCESS) len[0] = 1; return ret; } buflen = rlen*4; buf = (unsigned char*)grib_context_malloc(a->parent->h->context,buflen); for(i=0; i < rlen;i++){ grib_encode_unsigned_longb(buf,grib_ibm_to_long(val[i]), &off, 32); } ret = grib_set_long_internal(a->parent->h,grib_arguments_get_name(a->parent->h,self->arg,0),rlen); if(ret == GRIB_SUCCESS) grib_buffer_replace(a, buf, buflen,1,1); else *len = 0; grib_context_free(a->parent->h->context,buf); a->length = byte_count(a); return ret; }
int pack_long_unsigned_helper(grib_accessor* a, const long* val, size_t *len, int check) { grib_accessor_unsigned* self = (grib_accessor_unsigned*)a; int ret = 0; long off = 0; long rlen = 0; int err = 0; size_t buflen = 0; unsigned char *buf = NULL; unsigned long i = 0; unsigned long missing = 0; err=grib_value_count(a,&rlen); if (err) return err; if(a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) { Assert(self->nbytes <= 4); missing = ones[self->nbytes]; } if (a->flags & GRIB_ACCESSOR_FLAG_TRANSIENT) { a->vvalue->lval=val[0]; if(missing && val[0] == GRIB_MISSING_LONG) a->vvalue->missing=1; else a->vvalue->missing=0; return GRIB_SUCCESS; } if(*len < 1) { grib_context_log(a->parent->h->context, GRIB_LOG_ERROR, "Wrong size for %s it contains %d values ", a->name , 1 ); len[0] = 0; return GRIB_ARRAY_TOO_SMALL; } if (rlen == 1) { long v = val[0]; if (missing) if(v == GRIB_MISSING_LONG) v = missing; /* Check if value fits into number of bits */ if (check) { const long nbits = self->nbytes*8; /* See GRIB-23 and GRIB-262 */ if (! value_is_missing(v) ) { if (v < 0) { grib_context_log(a->parent->h->context, GRIB_LOG_ERROR, "Key \"%s\": Trying to encode a negative value of %ld for key of type unsigned\n", a->name, v); return GRIB_ENCODING_ERROR; } if (nbits < 32) { unsigned long maxval = (1 << nbits)-1; if (v > maxval) { grib_context_log(a->parent->h->context, GRIB_LOG_ERROR, "Key \"%s\": Trying to encode value of %ld but the maximum allowable value is %ld (number of bits=%ld)\n", a->name, v, maxval, nbits); return GRIB_ENCODING_ERROR; } } } } off = a->offset*8; ret = grib_encode_unsigned_long(a->parent->h->buffer->data, v, &off, self->nbytes*8); if (ret == GRIB_SUCCESS) len[0] = 1; if (*len > 1) grib_context_log(a->parent->h->context, GRIB_LOG_WARNING, "grib_accessor_unsigned : Trying to pack %d values in a scalar %s, packing first value", *len, a->name ); len[0] = 1; return ret; } /* TODO: We assume that there are no missing values if there are more that 1 value */ buflen = *len*self->nbytes; buf = (unsigned char*)grib_context_malloc(a->parent->h->context,buflen); for(i=0; i < *len;i++) grib_encode_unsigned_long(buf, val[i] , &off, self->nbytes*8); ret = grib_set_long_internal(a->parent->h,grib_arguments_get_name(a->parent->h,self->arg,0),*len); if(ret == GRIB_SUCCESS) grib_buffer_replace(a, buf, buflen,1,1); else *len = 0; grib_context_free(a->parent->h->context,buf); return ret; }
static int pack_double(grib_accessor* a, const double* val, size_t *len) { grib_accessor_data_complex_packing* self = (grib_accessor_data_complex_packing*)a; size_t i = 0; int ret = GRIB_SUCCESS; long hcount = 0; long lcount = 0; long hpos = 0; long lup = 0; long mmax = 0; long n_vals = 0; double *scals = NULL; double s = 0; double d = 0; unsigned char* buf = NULL; size_t buflen = 0; size_t hsize = 0; size_t lsize = 0; unsigned char* hres = NULL; unsigned char* lres = NULL; long lpos = 0; long maxv = 0; long offsetdata = 0; long bits_per_value = 0; double reference_value = 0; long binary_scale_factor = 0; long decimal_scale_factor = 0; long laplacianOperatorIsSet = 0; double laplacianOperator = 0; long sub_j= 0; long sub_k= 0; long sub_m= 0; long pen_j= 0; long pen_k= 0; long pen_m= 0; long GRIBEX_sh_bug_present =0; long ieee_floats =0; double min = 0; double max = 0; double current_val = 0; short mixmax_unset = 0; int bytes; encode_float_proc encode_float = NULL; if (*len ==0) return GRIB_NO_VALUES; if((ret = grib_get_long_internal(a->parent->h,self->offsetdata,&offsetdata)) != 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->decimal_scale_factor,&decimal_scale_factor)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(a->parent->h,self->GRIBEX_sh_bug_present,&GRIBEX_sh_bug_present)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(a->parent->h,self->ieee_floats,&ieee_floats)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(a->parent->h,self->laplacianOperatorIsSet,&laplacianOperatorIsSet)) != GRIB_SUCCESS) return ret; if((ret = grib_get_double_internal(a->parent->h,self->laplacianOperator,&laplacianOperator)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(a->parent->h,self->sub_j,&sub_j)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(a->parent->h,self->sub_k,&sub_k)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(a->parent->h,self->sub_m,&sub_m)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(a->parent->h,self->pen_j,&pen_j)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(a->parent->h,self->pen_k,&pen_k)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(a->parent->h,self->pen_m,&pen_m)) != GRIB_SUCCESS) return ret; self->dirty=1; switch (ieee_floats) { case 0: encode_float =grib_ibm_to_long; bytes=4; break; case 1: encode_float =grib_ieee_to_long; bytes=4; break; case 2: encode_float =grib_ieee64_to_long; bytes=8; break; default: return GRIB_NOT_IMPLEMENTED; } Assert (sub_j == sub_k); Assert( sub_j == sub_m); Assert (pen_j == pen_k); Assert( pen_j == pen_m); n_vals = (pen_j+1)*(pen_j+2); d = grib_power(decimal_scale_factor,10) ; if(*len != n_vals){ grib_context_log(a->parent->h->context,GRIB_LOG_ERROR,"COMPLEX_PACKING : wrong number of values, expected %d - got %d",n_vals,*len); return GRIB_INTERNAL_ERROR; } if (pen_j == sub_j) { double* values; if (d) { values=(double*)grib_context_malloc_clear(a->parent->h->context,sizeof(double)*n_vals); for (i=0;i<n_vals;i++) values[i]=val[i]*d; } else { values=(double*)val; } buflen=n_vals*bytes; buf = (unsigned char*)grib_context_malloc_clear(a->parent->h->context,buflen); grib_ieee_encode_array(a->parent->h->context,values,n_vals,bytes,buf); if (d) grib_context_free(a->parent->h->context,values); grib_buffer_replace(a, buf, buflen,1,1); grib_context_free(a->parent->h->context,buf); return 0; } if(!laplacianOperatorIsSet) { laplacianOperator = calculate_pfactor(a->parent->h->context,val,pen_j,sub_j); if((ret = grib_set_double_internal(a->parent->h,self->laplacianOperator,laplacianOperator)) != GRIB_SUCCESS) return ret; grib_get_double_internal(a->parent->h,self->laplacianOperator,&laplacianOperator); } /* printf("PACKING LAPLACE set=%ld value=%.20f\n",laplacianOperatorIsSet,laplacianOperator); */ hsize = 4*(sub_k+1)*(sub_k+2); lsize = ((n_vals - ((sub_k+1)*(sub_k+2)))*bits_per_value)/8; buflen = hsize+lsize; buf = (unsigned char*)grib_context_malloc(a->parent->h->context,buflen); hres = buf; lres = buf+hsize; maxv = pen_j+1; lpos = 0; hpos = 0; scals = (double*) grib_context_malloc(a->parent->h->context,maxv*sizeof(double)); Assert(scals); scals[0] =0; for(i=1;i<maxv;i++) scals[i] = ((double)pow(i*(i+1),laplacianOperator)); i=0; mmax = 0; maxv = pen_j+1; i=0; lcount=0; hcount=0; sub_k = sub_j; while(maxv>0) { lup=mmax; if(sub_k>=0) { i += 2*(sub_k+1); lup += sub_k+1 ; hcount += sub_k+1 ; sub_k--; } for(lcount=hcount; lcount < maxv ; lcount++) { current_val = ((val[i++]*d) * scals[lup]); if(mixmax_unset == 0){ max = current_val; min = current_val; mixmax_unset = 1; } if(current_val > max) max = current_val; if(current_val < min) min = current_val; current_val = ((val[i++]*d) * scals[lup]); if(current_val > max) max = current_val; if(current_val < min) min = current_val; lup++; } maxv--; hcount=0; mmax++; } 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); exit(GRIB_INTERNAL_ERROR); } binary_scale_factor = grib_get_binary_scale_fact(max,reference_value,bits_per_value,&ret); if (ret==GRIB_UNDERFLOW) { d=0; binary_scale_factor = 0; reference_value=0; } s = grib_power(-binary_scale_factor,2); /* printf("D : %.30f\n",d); */ i=0; mmax = 0; maxv = pen_j+1; i=0; lcount=0; hcount=0; sub_k = sub_j; while(maxv>0) { lup=mmax; if(sub_k>=0) { for(hcount=0;hcount<sub_k+1;hcount++) { if ( GRIBEX_sh_bug_present && hcount==sub_k ) { /* _test(val[i]*d*scals[lup],1); */ grib_encode_unsigned_long(hres, encode_float((val[i++]*d)*scals[lup]) , &hpos, 32); /* _test(val[i]*d*scals[lup],1); */ grib_encode_unsigned_long(hres, encode_float((val[i++]*d)*scals[lup]) , &hpos, 32); }else{ /* _test(val[i]*d,0); */ grib_encode_unsigned_long(hres, encode_float(val[i++]*d) , &hpos, 32); /* _test(val[i]*d,0); */ grib_encode_unsigned_long(hres, encode_float(val[i++]*d) , &hpos, 32); } lup++; } sub_k--; } #if FAST_BIG_ENDIAN grib_encode_double_array_complex((maxv-hcount)*2,&(val[i]),bits_per_value,reference_value,&(scals[lup]),d,s,lres,&lpos); i+=(maxv-hcount)*2; #else if (bits_per_value % 8) { for(lcount=hcount; lcount < maxv ; lcount++) { current_val = (((((val[i++]*d) * scals[lup])-reference_value)*s)+0.5); if(current_val < 0) grib_context_log(a->parent->h->context,GRIB_LOG_ERROR, "COMPLEX_PACKING : negative coput before packing (%g)", current_val); grib_encode_unsigned_longb(lres, current_val, &lpos, bits_per_value); current_val = (((((val[i++]*d) * scals[lup])-reference_value)*s)+0.5); if(current_val < 0) grib_context_log(a->parent->h->context,GRIB_LOG_ERROR, "COMPLEX_PACKING : negative coput before packing (%g)", current_val); grib_encode_unsigned_longb(lres, current_val, &lpos, bits_per_value); lup++; } } else { for(lcount=hcount; lcount < maxv ; lcount++) { current_val = (((((val[i++]*d) * scals[lup])-reference_value)*s)+0.5); if(current_val < 0) grib_context_log(a->parent->h->context,GRIB_LOG_ERROR, "COMPLEX_PACKING : negative coput before packing (%g)", current_val); grib_encode_unsigned_long(lres, current_val, &lpos, bits_per_value); current_val = (((((val[i++]*d) * scals[lup])-reference_value)*s)+0.5); if(current_val < 0) grib_context_log(a->parent->h->context,GRIB_LOG_ERROR, "COMPLEX_PACKING : negative coput before packing (%g)", current_val); grib_encode_unsigned_long(lres, current_val, &lpos, bits_per_value); lup++; } } #endif maxv--; hcount=0; mmax++; } if(((hpos/8) != hsize) &&((lpos/8) != lsize)) { grib_context_log(a->parent->h->context,GRIB_LOG_ERROR, "COMPLEX_PACKING : Mismatch in packing between high resolution and low resolution part"); grib_context_free(a->parent->h->context,buf); grib_context_free(a->parent->h->context,scals); return GRIB_INTERNAL_ERROR; } buflen = ((hpos + lpos)/8); if((ret = grib_set_double_internal(a->parent->h,self->reference_value, reference_value)) != GRIB_SUCCESS) return ret; { /* Make sure we can decode it again */ double ref = 1e-100; grib_get_double_internal(a->parent->h,self->reference_value,&ref); Assert(ref == reference_value); } if((ret = grib_set_long_internal(a->parent->h,self->binary_scale_factor, binary_scale_factor)) != GRIB_SUCCESS) return ret; grib_buffer_replace(a, buf, buflen,1,1); grib_context_free(a->parent->h->context,buf); grib_context_free(a->parent->h->context,scals); return ret; }