GF_Err gf_bifs_dec_unquant_field(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field) { Bool HasQ; u8 QType, AType; u32 NbBits; Fixed b_min, b_max; SFVec3f BMin, BMax; GF_Err e; /*check QP*/ if (!codec->ActiveQP) return GF_EOS; /*check FieldType*/ switch (field->fieldType) { case GF_SG_VRML_SFINT32: case GF_SG_VRML_SFFLOAT: case GF_SG_VRML_SFROTATION: case GF_SG_VRML_SFVEC2F: case GF_SG_VRML_SFVEC3F: break; case GF_SG_VRML_SFCOLOR: break; default: return GF_EOS; } /*check NDT*/ HasQ = gf_bifs_get_aq_info(node, field->fieldIndex, &QType, &AType, &b_min, &b_max, &NbBits); if (!HasQ || !QType) return GF_EOS; /*get NbBits for QP14 (QC_COORD_INDEX)*/ if (QType == QC_COORD_INDEX) { NbBits = gf_bifs_dec_qp14_get_bits(codec); /*QP14 is always on, not having NbBits set means the coord field is set after the index field, hence not decodable*/ if (!NbBits) return GF_NON_COMPLIANT_BITSTREAM; } BMin.x = BMin.y = BMin.z = b_min; BMax.x = BMax.y = BMax.z = b_max; /*check is the QP is on and retrieves the bounds*/ if (!Q_IsTypeOn(codec->ActiveQP, QType, &NbBits, &BMin, &BMax)) return GF_EOS; /*ok the field is Quantized, dequantize*/ switch (QType) { //these are all SFFloat quantized on n fields case QC_3DPOS: case QC_2DPOS: case QC_ORDER: case QC_COLOR: case QC_TEXTURE_COORD: case QC_ANGLE: case QC_SCALE: case QC_INTERPOL_KEYS: case QC_SIZE_3D: case QC_SIZE_2D: e = Q_DecFloat(codec, bs, field->fieldType, BMin, BMax, NbBits, field->far_ptr); break; //SFInt types case QC_LINEAR_SCALAR: case QC_COORD_INDEX: e = Q_DecInt(codec, bs, QType, (SFInt32) b_min, NbBits, field->far_ptr); break; //normalized fields (normals and vectors) case QC_NORMALS: //normal quant is only for SFVec3F if (field->fieldType != GF_SG_VRML_SFVEC3F) return GF_NON_COMPLIANT_BITSTREAM; e = Q_DecNormal(codec, bs, NbBits, field->far_ptr); break; case QC_ROTATION: //normal quant is only for SFRotation if (field->fieldType != GF_SG_VRML_SFROTATION) return GF_NON_COMPLIANT_BITSTREAM; e = Q_DecRotation(codec, bs, NbBits, field->far_ptr); break; default: return GF_BAD_PARAM; } if (e) return e; return GF_OK; }
M4Err BD_UnquantizeField(BifsDecoder *codec, BitStream *bs, SFNode *node, FieldInfo *field) { Bool HasQ; u8 QType, AType; u32 NbBits; Float b_min, b_max; SFVec3f BMin, BMax; M4Err e; /*check QP*/ if (!codec->ActiveQP) return M4FieldNotQuantized; /*check FieldType*/ switch (field->fieldType) { case FT_SFInt32: case FT_SFFloat: case FT_SFRotation: case FT_SFVec2f: case FT_SFVec3f: break; case FT_SFColor: break; default: return M4FieldNotQuantized; } /*check NDT*/ HasQ = Node_GetAQInfo(node, field->fieldIndex, &QType, &AType, &b_min, &b_max, &NbBits); if (!HasQ || !QType) return M4FieldNotQuantized; /*get NbBits for QP14 (QC_COORD_INDEX)*/ if (QType == QC_COORD_INDEX) { NbBits = BD_GetCoordBits(codec); /*QP14 is always on, not having NbBits set means the coord field is set after the index field, hence not decodable*/ if (!NbBits) return M4NonCompliantBitStream; } BMin.x = BMin.y = BMin.z = b_min; BMax.x = BMax.y = BMax.z = b_max; /*check is the QP is on and retrieves the bounds*/ if (!Q_IsTypeOn(codec->ActiveQP, QType, &NbBits, &BMin, &BMax)) return M4FieldNotQuantized; /*ok the field is Quantized, dequantize*/ switch (QType) { //these are all SFFloat quantized on n fields case QC_3DPOS: case QC_2DPOS: case QC_ORDER: case QC_COLOR: case QC_TEXTURE_COORD: case QC_ANGLE: case QC_SCALE: case QC_INTERPOL_KEYS: case QC_SIZE_3D: case QC_SIZE_2D: e = Q_DecFloat(codec, bs, field->fieldType, BMin, BMax, NbBits, field->far_ptr); break; //SFInt types case QC_LINEAR_SCALAR: case QC_COORD_INDEX: e = Q_DecInt(codec, bs, QType, (SFInt32) b_min, NbBits, field->far_ptr); break; //normalized fields (normals and vectors) case QC_NORMALS: //normal quant is only for SFVec3F if (field->fieldType != FT_SFVec3f) return M4InvalidNode; e = Q_DecNormal(codec, bs, NbBits, field->far_ptr); break; case QC_ROTATION: //normal quant is only for SFRotation if (field->fieldType != FT_SFRotation) return M4InvalidNode; e = Q_DecRotation(codec, bs, NbBits, field->far_ptr); break; default: return M4BadParam; } if (e) return e; return M4OK; }