float StreamPeer::get_float() { uint8_t buf[4]; get_data(buf, 4); if (big_endian) { uint32_t *p32 = (uint32_t *)buf; *p32 = BSWAP32(*p32); } return decode_float(buf); }
void decode_vector_xyz(CBitRead& entityBitBuffer, const CSVCMsg_SendTable::sendprop_t* pSendProp, vector_t& v) { v.x = decode_float(entityBitBuffer, pSendProp); v.y = decode_float(entityBitBuffer, pSendProp); //don't read in the third component for normals if(0 == (pSendProp->flags() & SPROP_NORMAL)) { v.z = decode_float(entityBitBuffer, pSendProp); } else { int signbit = entityBitBuffer.ReadOneBit(); float v0v0v1v1 = v.x * v.x + v.y * v.y; if(v0v0v1v1 < 1.0f) { v.z = sqrtf(1.0f - v0v0v1v1); } else { v.z = 0.0f; } if(signbit) { v.z *= -1.0f; } } }
prop_t* decode_prop(CBitRead& entityBitBuffer, FlattenedPropEntry* pFlattenedProp, uint32_t uClass, int nFieldIndex) { const CSVCMsg_SendTable::sendprop_t* pSendProp = pFlattenedProp->m_prop; prop_t* pResult = 0; if(pSendProp->type() != DPT_Array && pSendProp->type() != DPT_DataTable) { pResult = new prop_t((send_prop_type_t)(pSendProp->type())); } switch(pSendProp->type()) { case DPT_Int: pResult->m_value.m_int = decode_int(entityBitBuffer, pSendProp); break; case DPT_Float: pResult->m_value.m_float = decode_float(entityBitBuffer, pSendProp); break; case DPT_Vector: decode_vector_xyz(entityBitBuffer, pSendProp, pResult->m_value.m_vector); break; case DPT_VectorXY: decode_vector_xy(entityBitBuffer, pSendProp, pResult->m_value.m_vector); break; case DPT_String: pResult->m_value.m_pString = decode_string(entityBitBuffer, pSendProp); break; case DPT_Array: pResult = decode_array(entityBitBuffer, pFlattenedProp, pSendProp->num_elements(), uClass, nFieldIndex); break; case DPT_DataTable: break; case DPT_Int64: pResult->m_value.m_int64 = decode_int64(entityBitBuffer, pSendProp); break; } return pResult; }
static int unpack_double(grib_accessor* a, double* val, size_t *len) { grib_accessor_data_sh_unpacked* self = (grib_accessor_data_sh_unpacked*)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; */ double dummy=0; 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 err=0; decode_float_proc decode_float = NULL; n_vals = 0; 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(grib_handle_of_accessor(a),self->offsetdata,&offsetdata)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(grib_handle_of_accessor(a),self->GRIBEX_sh_bug_present,&GRIBEX_sh_bug_present)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(grib_handle_of_accessor(a),self->ieee_floats,&ieee_floats)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(grib_handle_of_accessor(a),self->sub_j,&sub_j)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(grib_handle_of_accessor(a),self->sub_k,&sub_k)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(grib_handle_of_accessor(a),self->sub_m,&sub_m)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(grib_handle_of_accessor(a),self->pen_j,&pen_j)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(grib_handle_of_accessor(a),self->pen_k,&pen_k)) != GRIB_SUCCESS) return ret; if((ret = grib_get_long_internal(grib_handle_of_accessor(a),self->pen_m,&pen_m)) != GRIB_SUCCESS) return ret; self->dirty=0; switch (ieee_floats) { case 0: decode_float=grib_long_to_ibm; break; case 1: decode_float=grib_long_to_ieee; break; case 2: decode_float=grib_long_to_ieee64; 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*)grib_handle_of_accessor(a)->buffer->data; maxv = pen_j+1; buf += offsetdata; hres = buf; lres = buf; packed_offset = offsetdata + 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->context,maxv*sizeof(double)); Assert(scals); if((ret = grib_get_double_internal(grib_handle_of_accessor(a),self->laplacianOperator,&laplacianOperator)) != GRIB_SUCCESS) return ret; scals[0] = 0; for(i=1;i<maxv;i++){ operat = pow(i*(i+1),laplacianOperator); if(operat != 0) scals[i] = (1.0/operat); else{ scals[i] = 0; } } 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; */ for(lcount=hcount; lcount < maxv ; lcount++) { dummy = (double) ((grib_decode_unsigned_long(lres, &lpos, bits_per_value)*s)+reference_value); dummy = (double) ((grib_decode_unsigned_long(lres, &lpos, bits_per_value)*s)+reference_value); lup++; } maxv--; hcount=0; mmax++; } Assert(*len >= i); *len = n_vals; if(d != 1) { for(i=0;i<*len;i++) val[i++] *= d; } (void)dummy; /* suppress gcc warning */ grib_context_free(a->context,scals); return ret; }
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len) { const uint8_t *buf = p_buffer; int len = p_len; if (len < 4) { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); } uint32_t type = decode_uint32(buf); ERR_FAIL_COND_V((type & ENCODE_MASK) >= Variant::VARIANT_MAX, ERR_INVALID_DATA); buf += 4; len -= 4; if (r_len) *r_len = 4; switch (type & ENCODE_MASK) { case Variant::NIL: { r_variant = Variant(); } break; case Variant::BOOL: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); bool val = decode_uint32(buf); r_variant = val; if (r_len) (*r_len) += 4; } break; case Variant::INT: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); if (type & ENCODE_FLAG_64) { int64_t val = decode_uint64(buf); r_variant = val; if (r_len) (*r_len) += 8; } else { int32_t val = decode_uint32(buf); r_variant = val; if (r_len) (*r_len) += 4; } } break; case Variant::REAL: { ERR_FAIL_COND_V(len < (int)4, ERR_INVALID_DATA); if (type & ENCODE_FLAG_64) { double val = decode_double(buf); r_variant = val; if (r_len) (*r_len) += 8; } else { float val = decode_float(buf); r_variant = val; if (r_len) (*r_len) += 4; } } break; case Variant::STRING: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t strlen = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)strlen > len, ERR_INVALID_DATA); String str; str.parse_utf8((const char *)buf, strlen); r_variant = str; if (r_len) { if (strlen % 4) (*r_len) += 4 - strlen % 4; (*r_len) += 4 + strlen; } } break; // math types case Variant::VECTOR2: { ERR_FAIL_COND_V(len < (int)4 * 2, ERR_INVALID_DATA); Vector2 val; val.x = decode_float(&buf[0]); val.y = decode_float(&buf[4]); r_variant = val; if (r_len) (*r_len) += 4 * 2; } break; // 5 case Variant::RECT2: { ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Rect2 val; val.position.x = decode_float(&buf[0]); val.position.y = decode_float(&buf[4]); val.size.x = decode_float(&buf[8]); val.size.y = decode_float(&buf[12]); r_variant = val; if (r_len) (*r_len) += 4 * 4; } break; case Variant::VECTOR3: { ERR_FAIL_COND_V(len < (int)4 * 3, ERR_INVALID_DATA); Vector3 val; val.x = decode_float(&buf[0]); val.y = decode_float(&buf[4]); val.z = decode_float(&buf[8]); r_variant = val; if (r_len) (*r_len) += 4 * 3; } break; case Variant::TRANSFORM2D: { ERR_FAIL_COND_V(len < (int)4 * 6, ERR_INVALID_DATA); Transform2D val; for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { val.elements[i][j] = decode_float(&buf[(i * 2 + j) * 4]); } } r_variant = val; if (r_len) (*r_len) += 4 * 6; } break; case Variant::PLANE: { ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Plane val; val.normal.x = decode_float(&buf[0]); val.normal.y = decode_float(&buf[4]); val.normal.z = decode_float(&buf[8]); val.d = decode_float(&buf[12]); r_variant = val; if (r_len) (*r_len) += 4 * 4; } break; case Variant::QUAT: { ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Quat val; val.x = decode_float(&buf[0]); val.y = decode_float(&buf[4]); val.z = decode_float(&buf[8]); val.w = decode_float(&buf[12]); r_variant = val; if (r_len) (*r_len) += 4 * 4; } break; case Variant::RECT3: { ERR_FAIL_COND_V(len < (int)4 * 6, ERR_INVALID_DATA); Rect3 val; val.position.x = decode_float(&buf[0]); val.position.y = decode_float(&buf[4]); val.position.z = decode_float(&buf[8]); val.size.x = decode_float(&buf[12]); val.size.y = decode_float(&buf[16]); val.size.z = decode_float(&buf[20]); r_variant = val; if (r_len) (*r_len) += 4 * 6; } break; case Variant::BASIS: { ERR_FAIL_COND_V(len < (int)4 * 9, ERR_INVALID_DATA); Basis val; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { val.elements[i][j] = decode_float(&buf[(i * 3 + j) * 4]); } } r_variant = val; if (r_len) (*r_len) += 4 * 9; } break; case Variant::TRANSFORM: { ERR_FAIL_COND_V(len < (int)4 * 12, ERR_INVALID_DATA); Transform val; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { val.basis.elements[i][j] = decode_float(&buf[(i * 3 + j) * 4]); } } val.origin[0] = decode_float(&buf[36]); val.origin[1] = decode_float(&buf[40]); val.origin[2] = decode_float(&buf[44]); r_variant = val; if (r_len) (*r_len) += 4 * 12; } break; // misc types case Variant::COLOR: { ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Color val; val.r = decode_float(&buf[0]); val.g = decode_float(&buf[4]); val.b = decode_float(&buf[8]); val.a = decode_float(&buf[12]); r_variant = val; if (r_len) (*r_len) += 4 * 4; } break; case Variant::NODE_PATH: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t strlen = decode_uint32(buf); if (strlen & 0x80000000) { //new format ERR_FAIL_COND_V(len < 12, ERR_INVALID_DATA); Vector<StringName> names; Vector<StringName> subnames; StringName prop; uint32_t namecount = strlen &= 0x7FFFFFFF; uint32_t subnamecount = decode_uint32(buf + 4); uint32_t flags = decode_uint32(buf + 8); len -= 12; buf += 12; int total = namecount + subnamecount; if (flags & 2) total++; if (r_len) (*r_len) += 12; for (int i = 0; i < total; i++) { ERR_FAIL_COND_V((int)len < 4, ERR_INVALID_DATA); strlen = decode_uint32(buf); int pad = 0; if (strlen % 4) pad += 4 - strlen % 4; buf += 4; len -= 4; ERR_FAIL_COND_V((int)strlen + pad > len, ERR_INVALID_DATA); String str; str.parse_utf8((const char *)buf, strlen); if (i < namecount) names.push_back(str); else if (i < namecount + subnamecount) subnames.push_back(str); else prop = str; buf += strlen + pad; len -= strlen + pad; if (r_len) (*r_len) += 4 + strlen + pad; } r_variant = NodePath(names, subnames, flags & 1, prop); } else { //old format, just a string buf += 4; len -= 4; ERR_FAIL_COND_V((int)strlen > len, ERR_INVALID_DATA); String str; str.parse_utf8((const char *)buf, strlen); r_variant = NodePath(str); if (r_len) (*r_len) += 4 + strlen; } } break; /*case Variant::RESOURCE: { ERR_EXPLAIN("Can't marshallize resources"); ERR_FAIL_V(ERR_INVALID_DATA); //no, i'm sorry, no go } break;*/ case Variant::_RID: { r_variant = RID(); } break; case Variant::OBJECT: { r_variant = (Object *)NULL; } break; case Variant::DICTIONARY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); // bool shared = count&0x80000000; count &= 0x7FFFFFFF; buf += 4; len -= 4; if (r_len) { (*r_len) += 4; } Dictionary d; for (uint32_t i = 0; i < count; i++) { Variant key, value; int used; Error err = decode_variant(key, buf, len, &used); ERR_FAIL_COND_V(err, err); buf += used; len -= used; if (r_len) { (*r_len) += used; } err = decode_variant(value, buf, len, &used); ERR_FAIL_COND_V(err, err); buf += used; len -= used; if (r_len) { (*r_len) += used; } d[key] = value; } r_variant = d; } break; case Variant::ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); // bool shared = count&0x80000000; count &= 0x7FFFFFFF; buf += 4; len -= 4; if (r_len) { (*r_len) += 4; } Array varr; for (uint32_t i = 0; i < count; i++) { int used = 0; Variant v; Error err = decode_variant(v, buf, len, &used); ERR_FAIL_COND_V(err, err); buf += used; len -= used; varr.push_back(v); if (r_len) { (*r_len) += used; } } r_variant = varr; } break; // arrays case Variant::POOL_BYTE_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count > len, ERR_INVALID_DATA); PoolVector<uint8_t> data; if (count) { data.resize(count); PoolVector<uint8_t>::Write w = data.write(); for (int i = 0; i < count; i++) { w[i] = buf[i]; } w = PoolVector<uint8_t>::Write(); } r_variant = data; if (r_len) { if (count % 4) (*r_len) += 4 - count % 4; (*r_len) += 4 + count; } } break; case Variant::POOL_INT_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 > len, ERR_INVALID_DATA); PoolVector<int> data; if (count) { //const int*rbuf=(const int*)buf; data.resize(count); PoolVector<int>::Write w = data.write(); for (int i = 0; i < count; i++) { w[i] = decode_uint32(&buf[i * 4]); } w = PoolVector<int>::Write(); } r_variant = Variant(data); if (r_len) { (*r_len) += 4 + count * sizeof(int); } } break; case Variant::POOL_REAL_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 > len, ERR_INVALID_DATA); PoolVector<float> data; if (count) { //const float*rbuf=(const float*)buf; data.resize(count); PoolVector<float>::Write w = data.write(); for (int i = 0; i < count; i++) { w[i] = decode_float(&buf[i * 4]); } w = PoolVector<float>::Write(); } r_variant = data; if (r_len) { (*r_len) += 4 + count * sizeof(float); } } break; case Variant::POOL_STRING_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); PoolVector<String> strings; buf += 4; len -= 4; if (r_len) (*r_len) += 4; //printf("string count: %i\n",count); for (int i = 0; i < (int)count; i++) { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t strlen = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)strlen > len, ERR_INVALID_DATA); //printf("loaded string: %s\n",(const char*)buf); String str; str.parse_utf8((const char *)buf, strlen); strings.push_back(str); buf += strlen; len -= strlen; if (r_len) (*r_len) += 4 + strlen; if (strlen % 4) { int pad = 4 - (strlen % 4); buf += pad; len -= pad; if (r_len) { (*r_len) += pad; } } } r_variant = strings; } break; case Variant::POOL_VECTOR2_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 * 2 > len, ERR_INVALID_DATA); PoolVector<Vector2> varray; if (r_len) { (*r_len) += 4; } if (count) { varray.resize(count); PoolVector<Vector2>::Write w = varray.write(); for (int i = 0; i < (int)count; i++) { w[i].x = decode_float(buf + i * 4 * 2 + 4 * 0); w[i].y = decode_float(buf + i * 4 * 2 + 4 * 1); } int adv = 4 * 2 * count; if (r_len) (*r_len) += adv; len -= adv; buf += adv; } r_variant = varray; } break; case Variant::POOL_VECTOR3_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 * 3 > len, ERR_INVALID_DATA); PoolVector<Vector3> varray; if (r_len) { (*r_len) += 4; } if (count) { varray.resize(count); PoolVector<Vector3>::Write w = varray.write(); for (int i = 0; i < (int)count; i++) { w[i].x = decode_float(buf + i * 4 * 3 + 4 * 0); w[i].y = decode_float(buf + i * 4 * 3 + 4 * 1); w[i].z = decode_float(buf + i * 4 * 3 + 4 * 2); } int adv = 4 * 3 * count; if (r_len) (*r_len) += adv; len -= adv; buf += adv; } r_variant = varray; } break; case Variant::POOL_COLOR_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 * 4 > len, ERR_INVALID_DATA); PoolVector<Color> carray; if (r_len) { (*r_len) += 4; } if (count) { carray.resize(count); PoolVector<Color>::Write w = carray.write(); for (int i = 0; i < (int)count; i++) { w[i].r = decode_float(buf + i * 4 * 4 + 4 * 0); w[i].g = decode_float(buf + i * 4 * 4 + 4 * 1); w[i].b = decode_float(buf + i * 4 * 4 + 4 * 2); w[i].a = decode_float(buf + i * 4 * 4 + 4 * 3); } int adv = 4 * 4 * count; if (r_len) (*r_len) += adv; len -= adv; buf += adv; } r_variant = carray; } break; default: { ERR_FAIL_V(ERR_BUG); } } return OK; }
void decode_vector_xy(CBitRead& entityBitBuffer, const CSVCMsg_SendTable::sendprop_t* pSendProp, vector_t& v) { v.x = decode_float(entityBitBuffer, pSendProp); v.y = decode_float(entityBitBuffer, pSendProp); }
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; }
void decode_cell(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos, struct cc_type *type, SV *output) { unsigned char *bytes; STRLEN bytes_len; if (unpack_bytes(aTHX_ input, len, pos, &bytes, &bytes_len) != 0) { sv_setsv(output, &PL_sv_undef); return; } switch (type->type_id) { case CC_TYPE_ASCII: case CC_TYPE_CUSTOM: case CC_TYPE_BLOB: decode_blob(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_BOOLEAN: decode_boolean(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_VARCHAR: case CC_TYPE_TEXT: decode_utf8(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_INET: decode_inet(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_SET: case CC_TYPE_LIST: decode_list(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_UUID: case CC_TYPE_TIMEUUID: decode_uuid(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_FLOAT: decode_float(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_DOUBLE: decode_double(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_DECIMAL: decode_decimal(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_VARINT: case CC_TYPE_BIGINT: case CC_TYPE_COUNTER: case CC_TYPE_TIMESTAMP: case CC_TYPE_SMALLINT: case CC_TYPE_TINYINT: case CC_TYPE_INT: decode_varint(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_DATE: decode_date(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_TIME: decode_time(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_MAP: decode_map(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_UDT: decode_udt(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_TUPLE: decode_tuple(aTHX_ bytes, bytes_len, type, output); break; default: sv_setsv(output, &PL_sv_undef); warn("Decoder doesn't yet understand type %d, returning undef instead", type->type_id); break; } }
float eightbyte_parse_float(uint64_t data, uint8_t bit_offset, uint8_t bit_size, float factor, float offset) { return decode_float(eightbyte_get_bitfield(data, bit_offset, bit_size, true), factor, offset); }
float bitfield_parse_float(const uint8_t source[], const uint16_t source_length, const uint8_t bit_offset, const uint8_t bit_size, const float factor, const float offset) { return decode_float(get_bitfield(source, source_length, bit_offset, bit_size), factor, offset); }
static int do_element(deark *c, lctx *d, i64 pos1, i64 nbytes_avail, i64 *bytes_used) { i64 ele_id; i64 ele_dlen; i64 pos = pos1; int retval = 0; const struct ele_id_info *einfo; const char *ele_name; int saved_indent_level; unsigned int dtype; int should_call_start_handler = 0; int should_decode_default = 0; int should_print_NOT_DECODING_msg = 0; int should_call_end_handler = 0; int len_ret; char tmpbuf[80]; de_dbg_indent_save(c, &saved_indent_level); de_dbg(c, "element at %"I64_FMT", max_len=%"I64_FMT, pos1, nbytes_avail); de_dbg_indent(c, 1); if(1!=get_var_size_int(c->infile, &ele_id, &pos, nbytes_avail)) { de_err(c, "Failed to read ID of element at %"I64_FMT, pos1); goto done; } einfo = find_ele_id_info(ele_id); if(einfo && einfo->name) ele_name = einfo->name; else ele_name = "?"; if(einfo) dtype = einfo->flags & 0xff; else dtype = 0; de_dbg(c, "id: 0x%"U64_FMTx" (%s)", (u64)ele_id, ele_name); if(d->show_encoded_id) { print_encoded_id(c, d, pos1, pos-pos1); } len_ret = get_var_size_int(c->infile, &ele_dlen, &pos, pos1+nbytes_avail-pos); if(len_ret==1) { de_snprintf(tmpbuf, sizeof(tmpbuf), "%"I64_FMT, ele_dlen); } else if(len_ret==2) { ele_dlen = c->infile->len - pos; de_strlcpy(tmpbuf, "unknown", sizeof(tmpbuf)); } else { de_err(c, "Failed to read length of element at %"I64_FMT, pos1); goto done; } de_dbg(c, "data at %"I64_FMT", dlen=%s, type=%s", pos, tmpbuf, get_type_name(dtype)); if(len_ret==2) { // EBML does not have any sort of end-of-master-element marker, which // presents a problem when a master element has an unknown length. // // EBML's "solution" is this: // "The end of an Unknown-Sized Element is determined by whichever // comes first: the end of the file or the beginning of the next EBML // Element, defined by this document or the corresponding EBML Schema, // that is not independently valid as Descendant Element of the // Unknown-Sized Element." // // This would appear to require a sophisticated, high-level algorithm // with 100% complete knowledge of the latest version of the specific // application format. We do not have such an algorithm. de_err(c, "EBML files with unknown-length elements are not supported"); goto done; } if(pos + ele_dlen > c->infile->len) { de_err(c, "Element at %"I64_FMT" goes beyond end of file", pos1); goto done; } if(einfo) { should_decode_default = 1; if(einfo->flags & 0x0200) { should_decode_default = 0; } else if((einfo->flags & 0x0100) && c->debug_level<2) { should_decode_default = 0; should_print_NOT_DECODING_msg = 1; } } if(should_decode_default && einfo && einfo->hfn) { should_call_start_handler = 1; } if(should_decode_default && einfo && einfo->hfn && (einfo->flags & 0x0800)) { should_call_end_handler = 1; } if(should_call_start_handler) { struct handler_params hp; de_zeromem(&hp, sizeof(struct handler_params)); hp.dpos = pos; hp.dlen = ele_dlen; einfo->hfn(c, d, &hp); } if(should_decode_default) { switch(dtype) { case TY_m: do_element_sequence(c, d, pos, ele_dlen); break; case TY_u: decode_uint(c, d, einfo, pos, ele_dlen); break; case TY_f: decode_float(c, d, einfo, pos, ele_dlen); break; case TY_8: decode_string(c, d, einfo, pos, ele_dlen, DE_ENCODING_UTF8); break; case TY_s: decode_string(c, d, einfo, pos, ele_dlen, DE_ENCODING_PRINTABLEASCII); break; case TY_d: decode_date(c, d, einfo, pos, ele_dlen); break; } } else { if(should_print_NOT_DECODING_msg) { de_dbg(c, "[not decoding this element]"); } } if(should_call_end_handler) { struct handler_params hp; de_zeromem(&hp, sizeof(struct handler_params)); hp.dpos = pos; hp.dlen = ele_dlen; hp.end_flag = 1; einfo->hfn(c, d, &hp); } pos += ele_dlen; *bytes_used = pos - pos1; retval = 1; done: de_dbg_indent_restore(c, saved_indent_level); return retval; }