/** * Copyright 2005-2007 ECMWF * * Licensed under the GNU Lesser General Public License which * incorporates the terms and conditions of version 3 of the GNU * General Public License. * See LICENSE and gpl-3.0.txt for details. */ #include "grib_api_internal.h" static unsigned long calc_pow_2(unsigned long op){ unsigned long a = 1; while(op--) a*=2; return a; } static int calc_bits_needed(unsigned long spread){ int nbit = 0; if (spread == 0) return nbit; while (spread>0){ spread/=2; nbit++; } return nbit; } static int find_next_group(const unsigned long* vals, size_t len, unsigned long w, unsigned long l,unsigned long* nbits, unsigned long* groupsize, long* r_val){ long lmin = 0; long lmax = 0; size_t i = 0; if (len <=0 ) return GRIB_ARRAY_TOO_SMALL; lmin = vals[0]; lmax = lmin; while(i < len){ if(vals[i] < lmin) lmin = vals[i]; if(vals[i] > lmax) lmax = vals[i]; Assert((lmax-lmin) >= 0); *nbits = calc_bits_needed(lmax-lmin); *r_val = lmin; i++; *groupsize = i; if(*groupsize > l-2) return GRIB_SUCCESS; if(*nbits > w-2) return GRIB_SUCCESS; } return GRIB_SUCCESS; } void grib_free_second_order_groups(grib_context *c,second_order_packed* sp){ if(!sp) return; grib_context_free(c,sp->array_of_group_size); grib_context_free(c,sp->array_of_group_refs); grib_context_free(c,sp->array_of_group_width); grib_context_free(c,sp); } second_order_packed* grib_get_second_order_groups(grib_context *c, const unsigned long* vals, size_t len){ second_order_packed* s = grib_context_malloc_clear(c,sizeof(second_order_packed)); const unsigned long* group_val = vals; size_t nv = len; size_t i = 0; unsigned long nbit_per_group; unsigned long size_of_group; long ref_of_group; s->packed_byte_count = 0; s->nbits_per_group_size = 6; s->nbits_per_widths = 4; s->size_of_group_array = 0; while(find_next_group(group_val, nv, calc_pow_2(s->nbits_per_widths), calc_pow_2(s->nbits_per_group_size ), &nbit_per_group, &size_of_group, &ref_of_group) == GRIB_SUCCESS){ s->size_of_group_array += 1; nv -= size_of_group; group_val += size_of_group; s->packed_byte_count += size_of_group*nbit_per_group; } s->packed_byte_count = ((s->packed_byte_count+7)/8); s->array_of_group_size = grib_context_malloc_clear(c,sizeof(unsigned long)*s->size_of_group_array); s->array_of_group_width = grib_context_malloc_clear(c,sizeof(unsigned long)*s->size_of_group_array); s->array_of_group_refs = grib_context_malloc_clear(c,sizeof( long)*s->size_of_group_array); group_val = vals; nv = len; while(find_next_group(group_val, nv, calc_pow_2(s->nbits_per_widths), calc_pow_2(s->nbits_per_group_size ), &nbit_per_group, &size_of_group, &ref_of_group) == GRIB_SUCCESS){ nv -= size_of_group; group_val += size_of_group; Assert(isize_of_group_array); s->array_of_group_size[i] = size_of_group; s->array_of_group_width[i] = nbit_per_group; s->array_of_group_refs[i] = ref_of_group; i++; } return s; }