static int unpack_double(grib_accessor* a, double* val, size_t *len)
{
    grib_accessor_bits* self = (grib_accessor_bits*)a;
    grib_accessor* x=NULL;
    unsigned char* p=NULL;
    grib_handle* h=grib_handle_of_accessor(a);
    long start,length;
    int ret=0;

    if(*len < 1) return GRIB_WRONG_ARRAY_SIZE;

    start=self->start;
    length=self->len;

    x=grib_find_accessor(grib_handle_of_accessor(a),self->argument);
    if (!x) return GRIB_NOT_FOUND;

    p  = h->buffer->data + grib_byte_offset(x);
    *val=grib_decode_unsigned_long(p,&start,length);

    *val=((long)*val+self->referenceValue)/self->scale;

    *len=1;

    return ret;
}
Пример #2
0
static int    pack_long   (grib_accessor* a, const long *val, size_t *len)
{
	grib_accessor_bit *ac = (grib_accessor_bit*) a;
	grib_accessor* owner = NULL;
	unsigned char *mdata = 0;
	if(*len < 1)
	{
		grib_context_log(a->parent->h->context, GRIB_LOG_ERROR, "grib_accessor_bit : pack_long : At least one value to pack for %s", a->name );
		*len = 0;
		return GRIB_ARRAY_TOO_SMALL;
	}

	owner = grib_find_accessor(a->parent->h,ac->owner);

	if(!owner){
		grib_context_log(a->parent->h->context, GRIB_LOG_ERROR, "grib_accessor_bit : Cannot get the owner %s for computing the bit value of %s ",ac->owner, a->name);
		*len = 0;
		return GRIB_NOT_FOUND;
	}

	mdata = a->parent->h->buffer->data;
	mdata += grib_byte_offset(owner);

	grib_set_bit( mdata,7-ac->bit_index , *val>0);

	*len = 1;
	return GRIB_SUCCESS;
}
static int unpack_bytes(grib_accessor* a, unsigned char* val, size_t *len)
{
  unsigned char* buf = a->parent->h->buffer->data;
  grib_accessor_g1bitmap* self = (grib_accessor_g1bitmap*)a;
  long tlen;
  int err;
  long length = grib_byte_count(a);
  long offset = grib_byte_offset(a);

  if(*len < length )
  {
    grib_context_log(a->parent->h->context, GRIB_LOG_ERROR, "Wrong size for %s it is %d bytes long\n", a->name ,length );
    *len = length;
    return GRIB_ARRAY_TOO_SMALL;
  }

  if ((err=grib_get_long_internal(a->parent->h, self->unusedBits, &tlen)) != GRIB_SUCCESS)
    grib_context_log(a->parent->h->context, GRIB_LOG_ERROR,
                     "grib_accessor_class_bitmap.unpack_bytes : cannot get %s err=%d",self->unusedBits,err);
  
  length-= tlen/8;
  memcpy(val,buf + offset,length );
  *len = length;

  return GRIB_SUCCESS;
}
static int  unpack_double(grib_accessor* a, double* val, size_t *len)
{
  grib_accessor_data_raw_packing *self =(grib_accessor_data_raw_packing*)a;
  unsigned char* buf = NULL;
  int bytes = 0;
  size_t nvals = 0;
  long inlen = grib_byte_count(a);

  long precision = 0;

  int code = GRIB_SUCCESS;

  if((code = grib_get_long_internal(a->parent->h,self->precision,&precision))
      != GRIB_SUCCESS)
    return code;

  self->dirty=0;

  buf =  (unsigned char*)a->parent->h->buffer->data;
  buf += grib_byte_offset(a);

  switch(precision)
  {
    case 1:
      bytes = 4;
      break;

    case 2:
      bytes = 8;
      break;

    default:
      return GRIB_NOT_IMPLEMENTED;
      break;
  }

  nvals = inlen / bytes;

  if(*len < nvals)
    return GRIB_ARRAY_TOO_SMALL;

  code=grib_ieee_decode_array(a->parent->h->context,buf,nvals,bytes,val);

  *len = nvals;

  return code;
}
static int  unpack_double_element(grib_accessor* a, size_t idx, double* val) {
  int ret=0;
  grib_accessor_data_raw_packing *self =(grib_accessor_data_raw_packing*)a;
  unsigned char* buf = NULL;
  int bytes = 0;
  size_t nvals = 0;
  long inlen = grib_byte_count(a);
  long pos;

  long precision = 0;

  if((ret = grib_get_long_internal(a->parent->h,self->precision,&precision))
      != GRIB_SUCCESS)
    return ret;

  self->dirty=0;

  buf =  (unsigned char*)a->parent->h->buffer->data;
  buf += grib_byte_offset(a);

  switch(precision)
  {
    case 1:
      bytes = 4;
      break;

    case 2:
      bytes = 8;
      break;

    default:
      return GRIB_NOT_IMPLEMENTED;
      break;
  }

  pos=bytes*idx;
  
  Assert(pos<=inlen);
  
  nvals = 1;
  buf+=pos;
  
  ret=grib_ieee_decode_array(a->parent->h->context,buf,nvals,bytes,val);

  return ret;
}
static int pack_long(grib_accessor* a, const long* val, size_t *len)
{
  grib_accessor_bits* self = (grib_accessor_bits*)a;
  grib_accessor* x=NULL;
  grib_handle* h=a->parent->h;
  unsigned char* p=NULL;
  long start,length;

  if(*len != 1) return GRIB_WRONG_ARRAY_SIZE;

  start  = self->start;
  length = self->len;
  
  x=grib_find_accessor(a->parent->h,self->argument);
  if (!x) return GRIB_NOT_FOUND;

  p=h->buffer->data + grib_byte_offset(x);
  return grib_encode_unsigned_longb(p,*val,&start,length);

}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
    grib_accessor_bits* self = (grib_accessor_bits*)a;
    grib_accessor* x=NULL;
    grib_handle* h=grib_handle_of_accessor(a);
    unsigned char* p=NULL;
    long start,length,lval;

    if(*len != 1) return GRIB_WRONG_ARRAY_SIZE;

    start  = self->start;
    length = self->len;

    x=grib_find_accessor(grib_handle_of_accessor(a),self->argument);
    if (!x) return GRIB_NOT_FOUND;

    p=h->buffer->data + grib_byte_offset(x);

    lval= round(*val * self->scale) - self->referenceValue;
    return grib_encode_unsigned_longb(p,lval,&start,length);
}
static int pack_long(grib_accessor* a, const long* val, size_t *len)
{
    grib_accessor_bits* self = (grib_accessor_bits*)a;
    grib_accessor* x=NULL;
    grib_handle* h=grib_handle_of_accessor(a);
    unsigned char* p=NULL;
    long start,length, maxval;

    if(*len != 1) return GRIB_WRONG_ARRAY_SIZE;

    if (get_native_type(a) == GRIB_TYPE_DOUBLE) {
        /* ECC-402 */
        const double dVal = (double)(*val);
        return pack_double(a, &dVal, len);
    }

    start  = self->start;
    length = self->len;

    x=grib_find_accessor(grib_handle_of_accessor(a),self->argument);
    if (!x) return GRIB_NOT_FOUND;

    /* Check the input value */
    if (*val < 0) {
        grib_context_log(h->context, GRIB_LOG_ERROR, "key=%s: value cannot be negative",a->name);
        return GRIB_ENCODING_ERROR;
    }
    maxval = (1 << length) - 1;
    if (*val > maxval){
        grib_context_log(h->context, GRIB_LOG_ERROR,
                "key=%s: Trying to encode value of %ld but the maximum allowable value is %ld (number of bits=%ld)",
                a->name, *val, maxval, length);
        return GRIB_ENCODING_ERROR;
    }

    p=h->buffer->data + grib_byte_offset(x);
    return grib_encode_unsigned_longb(p,*val,&start,length);
}
static int    unpack_long   (grib_accessor* a, long* val, size_t *len)
{
  grib_accessor_count_missing* self = (grib_accessor_count_missing*)a;
  unsigned char* p;
  int i;
  long size=0;
  long offset=0;
  long unusedBitsInBitmap=0;
  long numberOfDataPoints=0;
  grib_handle* h=a->parent->h;
  grib_accessor* bitmap=grib_find_accessor(a->parent->h,self->bitmap);

  *val=0;
  *len=1;
  if (!bitmap) return GRIB_SUCCESS;

  size=grib_byte_count(bitmap);
  offset=grib_byte_offset(bitmap);

  if (grib_get_long(h,self->unusedBitsInBitmap,&unusedBitsInBitmap) != GRIB_SUCCESS) { 
    if (grib_get_long(h,self->numberOfDataPoints,&numberOfDataPoints) != GRIB_SUCCESS) {
		grib_context_log(a->parent->h->context,GRIB_LOG_ERROR,"unable to count missing values");
		return GRIB_INTERNAL_ERROR;
	} 
	unusedBitsInBitmap=size*8-numberOfDataPoints;
  }

  p=a->parent->h->buffer->data+offset;

  size-=unusedBitsInBitmap/8;
  unusedBitsInBitmap= unusedBitsInBitmap % 8;

  for (i=0;i<size-1;i++) *val += bitsoff[*(p++)];

  *val += bitsoff[(*p) | used[unusedBitsInBitmap]];

  return GRIB_SUCCESS;
}
Пример #10
0
static int    unpack_long   (grib_accessor* a, long* val, size_t *len)
{
  grib_accessor_bits* self = (grib_accessor_bits*)a;
  grib_accessor* x=NULL;
  unsigned char* p=NULL;
  grib_handle* h=a->parent->h;
  long start,length;
  int ret=0;

  if(*len < 1) return GRIB_WRONG_ARRAY_SIZE;

  start=self->start;
  length=self->len;
  
  x=grib_find_accessor(a->parent->h,self->argument);
  if (!x) return GRIB_NOT_FOUND;

  p  = h->buffer->data + grib_byte_offset(x);
  *val=grib_decode_unsigned_long(p,&start,length);

  *len=1;

  return ret;
}
static int unpack_double(grib_accessor* a, double* values, size_t *len)
{
  grib_accessor_data_g1second_order_constant_width_packing* self =  (grib_accessor_data_g1second_order_constant_width_packing*)a;
  int ret=0;
  long numberOfGroups,numberOfSecondOrderPackedValues;
  long groupWidth=0;
  long* firstOrderValues=0;
  long* X=0;
  long numberPerRow=0;
  long pos=0;
  long widthOfFirstOrderValues=0;
  long jPointsAreConsecutive;
  unsigned char* buf = (unsigned char*)grib_handle_of_accessor(a)->buffer->data;
  long i,n;
  double reference_value;
  long binary_scale_factor;
  long decimal_scale_factor;
  double s,d;
  long* secondaryBitmap;

  buf += grib_byte_offset(a);

  if((ret=grib_get_long_internal(grib_handle_of_accessor(a),self->numberOfGroups,&numberOfGroups)) != GRIB_SUCCESS)
         return ret;

  if((ret=grib_get_long_internal(grib_handle_of_accessor(a),self->jPointsAreConsecutive,&jPointsAreConsecutive)) != GRIB_SUCCESS)
         return ret;

	if (jPointsAreConsecutive) {
	  if((ret=grib_get_long_internal(grib_handle_of_accessor(a),self->Ni,&numberPerRow)) != GRIB_SUCCESS)
         return ret;
	} else {
	  if((ret=grib_get_long_internal(grib_handle_of_accessor(a),self->Nj,&numberPerRow)) != GRIB_SUCCESS)
         return ret;
	}

  if((ret=grib_get_long_internal(grib_handle_of_accessor(a),self->widthOfFirstOrderValues,&widthOfFirstOrderValues)) != GRIB_SUCCESS)
         return ret;

  if((ret=grib_get_long_internal(grib_handle_of_accessor(a),self->binary_scale_factor,&binary_scale_factor)) != GRIB_SUCCESS)
         return ret;

  if((ret=grib_get_long_internal(grib_handle_of_accessor(a),self->decimal_scale_factor,&decimal_scale_factor)) != GRIB_SUCCESS)
         return ret;

  if((ret=grib_get_double_internal(grib_handle_of_accessor(a),self->reference_value,&reference_value)) != GRIB_SUCCESS)
         return ret;

  if((ret=grib_get_long_internal(grib_handle_of_accessor(a),self->numberOfSecondOrderPackedValues,
  					&numberOfSecondOrderPackedValues)) != GRIB_SUCCESS)
         return ret;

  if((ret=grib_get_long_internal(grib_handle_of_accessor(a),self->groupWidth, &groupWidth)) != GRIB_SUCCESS)
         return ret;

	secondaryBitmap=(long*)grib_context_malloc_clear(a->context,sizeof(long)*numberOfSecondOrderPackedValues);
	grib_decode_long_array(buf,&pos,1,numberOfSecondOrderPackedValues,secondaryBitmap);
	pos = 8 * ( (pos + 7 ) / 8);

	firstOrderValues=(long*)grib_context_malloc_clear(a->context,sizeof(long)*numberOfGroups);
	grib_decode_long_array(buf,&pos,widthOfFirstOrderValues,numberOfGroups,firstOrderValues);
	pos = 8 * ( (pos + 7 ) / 8);

	X=(long*)grib_context_malloc_clear(a->context,sizeof(long)*numberOfSecondOrderPackedValues);

	if (groupWidth>0) {
		grib_decode_long_array(buf,&pos,groupWidth,numberOfSecondOrderPackedValues,X);
		n=0;
		i=-1;
		while (n<numberOfSecondOrderPackedValues) {
			i+=secondaryBitmap[n];
			X[n]=firstOrderValues[i]+X[n];
			n++;
		}
	} else {
		n=0;
		i=-1;
		while (n<numberOfSecondOrderPackedValues) {
			i+=secondaryBitmap[n];
			X[n]=firstOrderValues[i];
			n++;
		}
	}


	/*
	{
	long extrabits = 16 * ( (pos + 15 ) / 16) - pos;
	printf("XXXXXXX extrabits=%ld pos=%ld\n",extrabits,pos);
	}
	*/

	s = grib_power(binary_scale_factor,2);
	d = grib_power(-decimal_scale_factor,10) ;
	for (i=0; i<numberOfSecondOrderPackedValues; i++) {
		values[i] = (double) (((X[i]*s)+reference_value)*d);
	}

	*len=numberOfSecondOrderPackedValues;
	grib_context_free(a->context,secondaryBitmap);
	grib_context_free(a->context,firstOrderValues);
	grib_context_free(a->context,X);
  
  return ret;
}
static int unpack_double(grib_accessor* a, double* values, size_t *len)
{
  grib_accessor_data_g1second_order_row_by_row_packing* self =  (grib_accessor_data_g1second_order_row_by_row_packing*)a;
  int ret=0;
  long numberOfGroups,numberOfSecondOrderPackedValues;
  long* groupWidths=0;
  long* firstOrderValues=0;
  long* X=0;
  long numberOfRows,numberOfColumns;
  long *numbersPerRow;
  long pos=0;
  long widthOfFirstOrderValues=0;
  long jPointsAreConsecutive;
  unsigned char* buf = (unsigned char*)a->parent->h->buffer->data;
  long k,i,j,n,Ni,Nj;
  double reference_value;
  long binary_scale_factor;
  long decimal_scale_factor;
  double s,d;
  size_t groupWidthsSize=0;
  int bitmapPresent=0;
  size_t plSize=0;
  long* pl=0;

  buf += grib_byte_offset(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->jPointsAreConsecutive,&jPointsAreConsecutive)) != GRIB_SUCCESS)
         return ret;

  if (self->bitmap) bitmapPresent=1;
  ret=grib_get_size(a->parent->h,self->pl,&plSize);
  if (ret==GRIB_SUCCESS) {
	  pl=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*plSize);
	  if((ret=grib_get_long_array(a->parent->h,self->pl,pl,&plSize)) != GRIB_SUCCESS)
         return ret;
  }

  if((ret=grib_get_long_internal(a->parent->h,self->Ni,&Ni)) != GRIB_SUCCESS)
         return ret;
  if((ret=grib_get_long_internal(a->parent->h,self->Nj,&Nj)) != GRIB_SUCCESS)
         return ret;
  if (jPointsAreConsecutive) {
  	numberOfRows=Ni;
	numberOfColumns=Nj;
  } else {
  	numberOfRows=Nj;
	numberOfColumns=Ni;
  }

  numbersPerRow=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfRows);
  if (bitmapPresent) {
	long *bitmap,*pbitmap;
	size_t numberOfPoints=Ni*Nj;

  	if (plSize) {
		numberOfPoints=0;
		for (i=0;i<numberOfRows;i++) numberOfPoints+=pl[i];
	} 
	bitmap=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfPoints);
	pbitmap=bitmap;
	grib_get_long_array(a->parent->h,self->bitmap,bitmap,&numberOfPoints);
  	if (plSize) {
		for (i=0;i<numberOfRows;i++) {
			for (j=0;j<pl[i];j++) {
				numbersPerRow[i]+=*(bitmap++);
			}
		}
	} else {
		for (i=0;i<numberOfRows;i++) {
			numbersPerRow[i]=0;
			for (j=0;j<Ni;j++) {
				numbersPerRow[i]+=*(bitmap++);
			}
		}
	}

	grib_context_free(a->parent->h->context,pbitmap);
  } else {
  	if (plSize) {
		for (i=0;i<numberOfRows;i++) numbersPerRow[i]=pl[i];
	} else {
		for (i=0;i<numberOfRows;i++) 
			numbersPerRow[i]=numberOfColumns;
	}
  }

  if((ret=grib_get_long_internal(a->parent->h,self->widthOfFirstOrderValues,&widthOfFirstOrderValues)) != 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->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_long_internal(a->parent->h,self->numberOfSecondOrderPackedValues,
  					&numberOfSecondOrderPackedValues)) != GRIB_SUCCESS)
         return ret;

  groupWidths=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfGroups);
  groupWidthsSize=numberOfGroups;
  if((ret=grib_get_long_array_internal(a->parent->h,self->groupWidths, groupWidths,&groupWidthsSize)) != GRIB_SUCCESS)
         return ret;

	firstOrderValues=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfGroups);
	grib_decode_long_array(buf,&pos,widthOfFirstOrderValues,numberOfGroups,firstOrderValues);
	pos = 8 * ( (pos + 7 ) / 8);

	X=grib_context_malloc_clear(a->parent->h->context,sizeof(long)*numberOfSecondOrderPackedValues);
	n=0;
	k=0;
	for (i=0; i<numberOfGroups; i++) {
		if (groupWidths[i]>0) {
				for (j=0;j<numbersPerRow[k];j++) {
					X[n]=grib_decode_unsigned_long(buf,&pos,groupWidths[i]);
					X[n]+=firstOrderValues[i];
					n++;
				}
		} else {
				for (j=0;j<numbersPerRow[k];j++) {
					X[n]=firstOrderValues[i];
					n++;
				}
		}
		k++;
	}

	s = grib_power(binary_scale_factor,2);
	d = grib_power(-decimal_scale_factor,10) ;
	for (i=0; i<n; i++) {
		values[i] = (double) (((X[i]*s)+reference_value)*d);
	}
	grib_context_free(a->parent->h->context,firstOrderValues);
	grib_context_free(a->parent->h->context,X);
	grib_context_free(a->parent->h->context,groupWidths);
	if (plSize) grib_context_free(a->parent->h->context,pl);
  
  return ret;
}
static long next_offset(grib_accessor* a)
{
    return grib_byte_offset(a) + grib_byte_count(a);
}
static int  unpack_double(grib_accessor* a, 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 *pscals=NULL,*pval=NULL;

    double s = 0;
    double d = 0;
    double laplacianOperator = 0;
    unsigned char* buf = NULL;
    unsigned char* hres = NULL;
    unsigned char* lres = NULL;
    unsigned long packed_offset;
    long   lpos = 0;

    long   maxv = 0;
    long   GRIBEX_sh_bug_present =0;
    long ieee_floats  = 0;

    long   offsetdata           = 0;
    long   bits_per_value          = 0;
    double reference_value      = 0;
    long   binary_scale_factor         = 0;
    long   decimal_scale_factor = 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;

    double operat= 0;
    int bytes;
    int err=0;

    decode_float_proc decode_float = NULL;

    err=grib_value_count(a,&n_vals);
    if (err) return err;

    if(*len < n_vals){
        *len = n_vals;
        return GRIB_ARRAY_TOO_SMALL;
    }

    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_double_internal(a->parent->h,self->reference_value,&reference_value))
            != 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->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_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=0;

    switch (ieee_floats) {
    case 0:
        decode_float=grib_long_to_ibm;
        bytes=4;
        break;
    case 1:
        decode_float=grib_long_to_ieee;
        bytes=4;
        break;
    case 2:
        decode_float=grib_long_to_ieee64;
        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);

    buf = (unsigned char*)a->parent->h->buffer->data;

    maxv = pen_j+1;

    buf  += grib_byte_offset(a);
    hres = buf;
    lres = buf;

    if (pen_j == sub_j) {
        n_vals = (pen_j+1)*(pen_j+2);
        d = grib_power(-decimal_scale_factor,10) ;
        grib_ieee_decode_array(a->parent->h->context,buf,n_vals,bytes,val);
        if (d) {
            for (i=0;i<n_vals;i++) val[i]*=d;
        }
        return 0;
    }

    packed_offset = grib_byte_offset(a) +  4*(sub_k+1)*(sub_k+2);

    lpos = 8*(packed_offset-offsetdata);

    s = grib_power(binary_scale_factor,2);
    d = grib_power(-decimal_scale_factor,10) ;

    scals   = (double*)grib_context_malloc(a->parent->h->context,maxv*sizeof(double));
    Assert(scals);

    scals[0] = 0;
    for(i=1;i<maxv;i++){
        operat = pow(i*(i+1),laplacianOperator);
        if(operat !=  0)
            scals[i] = (1.0/operat);
        else{
            grib_context_log(a->parent->h->context,GRIB_LOG_WARNING,
                    "COMPLEX_PACKING : problem with operator div by zero at index %d of %d \n",
                    i , maxv);
            scals[i] = 0;
        }
    }

    /*
  printf("UNPACKING LAPLACE=%.20f\n",laplacianOperator);

  printf("packed offset=%ld\n",packed_offset);
  for(i=0;i<maxv;i++)
    printf("scals[%d]=%g\n",i,scals[i]);*/

    i=0;

    while(maxv>0)
    {
        lup=mmax;
        if(sub_k>=0)
        {
            for(hcount=0;hcount<sub_k+1;hcount++)
            {
                val[i++] =  decode_float(grib_decode_unsigned_long(hres,&hpos,32))*d;
                val[i++] =  decode_float(grib_decode_unsigned_long(hres,&hpos,32))*d;

                if (GRIBEX_sh_bug_present && hcount==sub_k){
                    /*  bug in ecmwf data, last row (K+1)is scaled but should not */
                    val[i-2] *= scals[lup];
                    val[i-1] *= scals[lup];
                }
                lup++;
            }
            sub_k--;
        }

        pscals=scals+lup;
        pval=val+i;
#if FAST_BIG_ENDIAN
        grib_decode_double_array_complex(lres,
                &lpos,bits_per_value,
                reference_value,s,pscals,(maxv-hcount)*2,pval);
        i+=(maxv-hcount)*2;
#else
        (void)pscals; /* suppress gcc warning */
        (void)pval;   /* suppress gcc warning */
        for(lcount=hcount; lcount < maxv ; lcount++)
        {
            val[i++] =  (double) ((grib_decode_unsigned_long(lres, &lpos,
                    bits_per_value)*s)+reference_value)*scals[lup];
            val[i++] =  (double) ((grib_decode_unsigned_long(lres, &lpos,
                    bits_per_value)*s)+reference_value)*scals[lup];
            lup++;
        }
#endif

        maxv--;
        hcount=0;
        mmax++;
    }

    Assert(*len >= i);
    *len = i;

    if(d != 1) {
        for(i=0;i<*len;i++)
            val[i++] *= d;
    }

    grib_context_free(a->parent->h->context,scals);

    return ret;
}
static int  unpack_double(grib_accessor* a, double* val, size_t *len)
{
    grib_accessor_data_jpeg2000_packing *self =(grib_accessor_data_jpeg2000_packing*)a;

    int err = GRIB_SUCCESS;
    int i;
    size_t buflen = grib_byte_count(a);

    double bscale = 0;
    double dscale = 0;
    unsigned char* buf = NULL;
    size_t n_vals = 0;
    long nn=0;

    long binary_scale_factor = 0;
    long decimal_scale_factor = 0;
    double reference_value = 0;
    long bits_per_value =0;
    double units_factor=1.0;
    double units_bias=0.0;

    n_vals = 0;
    err=grib_value_count(a,&nn);
    n_vals=nn;
    if (err) return err;

    if(self->units_factor)
        grib_get_double_internal(a->parent->h,self->units_factor,&units_factor);

    if(self->units_bias)
        grib_get_double_internal(a->parent->h,self->units_bias,&units_bias);


    if((err = grib_get_long_internal(a->parent->h,self->bits_per_value,&bits_per_value)) != GRIB_SUCCESS)
        return err;
    if((err = grib_get_double_internal(a->parent->h,self->reference_value, &reference_value)) != GRIB_SUCCESS)
        return err;
    if((err = grib_get_long_internal(a->parent->h,self->binary_scale_factor, &binary_scale_factor)) != GRIB_SUCCESS)
        return err;
    if((err = grib_get_long_internal(a->parent->h,self->decimal_scale_factor, &decimal_scale_factor)) != GRIB_SUCCESS)
        return err;

    self->dirty=0;

    bscale = grib_power(binary_scale_factor,2);
    dscale = grib_power(-decimal_scale_factor,10);

    /* TODO: This should be called upstream */
    if(*len < n_vals)
        return GRIB_ARRAY_TOO_SMALL;

    /* Special case */

    if(bits_per_value == 0)
    {
        for(i = 0; i < n_vals; i++)
            val[i] = reference_value;
        *len = n_vals;
        return GRIB_SUCCESS;
    }

    buf = (unsigned char*)a->parent->h->buffer->data;
    buf += grib_byte_offset(a);

    switch (self->jpeg_lib) {
    case OPENJPEG_LIB:
        if ((err = grib_openjpeg_decode(a->parent->h->context,buf,&buflen,val,&n_vals)) != GRIB_SUCCESS)
            return err;
        break;
    case JASPER_LIB:
        if ((err = grib_jasper_decode(a->parent->h->context,buf,&buflen,val,&n_vals)) != GRIB_SUCCESS)
            return err;
        break;
    }

    *len = n_vals;

    for (i = 0; i < n_vals; i++) {
        val[i] = (val[i] * bscale + reference_value) * dscale;
    }
    if (units_factor != 1.0) {
        if (units_bias != 0.0)
            for (i=0;i<n_vals;i++) val[i]=val[i]*units_factor+units_bias;
        else
            for (i=0;i<n_vals;i++) val[i]*=units_factor;
    } else if (units_bias != 0.0)
        for (i=0;i<n_vals;i++) val[i]+=units_bias;

    return err;
}