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; }
GF_Err gf_bifs_dec_pred_mf_field(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field) { GF_Err e; Bool HasQ; u8 AType; Fixed b_min, b_max; u32 i, flag; PredMF pmf; memset(&pmf, 0, sizeof(PredMF)); HasQ = gf_bifs_get_aq_info(node, field->fieldIndex, &pmf.QType, &AType, &b_min, &b_max, &pmf.QNbBits); if (!HasQ || !pmf.QType) return GF_EOS; /*get NbBits for QP14 (QC_COORD_INDEX)*/ if (pmf.QType == QC_COORD_INDEX) pmf.QNbBits = gf_bifs_dec_qp14_get_bits(codec); pmf.BMin.x = pmf.BMin.y = pmf.BMin.z = b_min; pmf.BMax.x = pmf.BMax.y = pmf.BMax.z = b_max; /*check is the QP is on and retrieves the bounds*/ if (!Q_IsTypeOn(codec->ActiveQP, pmf.QType, &pmf.QNbBits, &pmf.BMin, &pmf.BMax)) return GF_EOS; switch (field->fieldType) { case GF_SG_VRML_MFCOLOR: case GF_SG_VRML_MFVEC3F: if (pmf.QType==QC_NORMALS) { pmf.num_comp = 2; break; } case GF_SG_VRML_MFROTATION: pmf.num_comp = 3; break; case GF_SG_VRML_MFVEC2F: pmf.num_comp = 2; break; case GF_SG_VRML_MFFLOAT: case GF_SG_VRML_MFINT32: pmf.num_comp = 1; break; default: return GF_NON_COMPLIANT_BITSTREAM; } /*parse array header*/ flag = gf_bs_read_int(bs, 5); pmf.num_fields = gf_bs_read_int(bs, flag); pmf.intra_mode = gf_bs_read_int(bs, 2); switch (pmf.intra_mode) { case 1: flag = gf_bs_read_int(bs, 5); pmf.intra_inter = gf_bs_read_int(bs, flag); /*no break*/ case 2: case 0: pmf.compNbBits = gf_bs_read_int(bs, 5); if (pmf.QType==1) pmf.num_bounds = 3; else if (pmf.QType==2) pmf.num_bounds = 2; else pmf.num_bounds = 1; for (i=0; i<pmf.num_bounds; i++) { flag = gf_bs_read_int(bs, pmf.QNbBits + 1); pmf.comp_min[i] = flag - (1<<pmf.QNbBits); } break; case 3: break; } pmf.dec = gp_bifs_aa_dec_new(bs); pmf.models[0] = gp_bifs_aa_model_new(); pmf.models[1] = gp_bifs_aa_model_new(); pmf.models[2] = gp_bifs_aa_model_new(); pmf.dir_model = gp_bifs_aa_model_new(); PMF_ResetModels(&pmf); gf_sg_vrml_mf_alloc(field->far_ptr, field->fieldType, pmf.num_fields); pmf.cur_field = 0; /*parse initial I*/ e = PMF_ParseIValue(&pmf, bs, field); if (e) return e; for (pmf.cur_field=1; pmf.cur_field<pmf.num_fields; pmf.cur_field++) { switch (pmf.intra_mode) { case 0: e = PMF_ParsePValue(&pmf, bs, field); break; /*NOT TESTED*/ case 1: if (!(pmf.cur_field % pmf.intra_inter)) { /*resync bitstream*/ gp_bifs_aa_dec_resync(pmf.dec); flag = gf_bs_read_int(bs, 1); /*update settings ?*/ if (flag) { e = PMF_UpdateArrayQP(&pmf, bs); if (e) goto err_exit; } e = PMF_ParseIValue(&pmf, bs, field); } else { e = PMF_ParsePValue(&pmf, bs, field); } break; /*NOT TESTED*/ case 2: /*is intra ? - WARNING: this is from the arithmetic context !!*/ flag = gp_bifs_aa_dec_get_bit(pmf.dec); if (flag) { /*resync bitstream*/ gp_bifs_aa_dec_resync_bit(pmf.dec); flag = gf_bs_read_int(bs, 1); /*update settings ?*/ if (flag) { e = PMF_UpdateArrayQP(&pmf, bs); if (e) goto err_exit; } e = PMF_ParseIValue(&pmf, bs, field); } else { e = PMF_ParsePValue(&pmf, bs, field); gp_bifs_aa_dec_flush(pmf.dec); } break; } if (e) goto err_exit; } if (pmf.intra_mode==2) { gp_bifs_aa_dec_resync_bit(pmf.dec); } else { gp_bifs_aa_dec_resync(pmf.dec); } err_exit: gp_bifs_aa_model_del(pmf.models[0]); gp_bifs_aa_model_del(pmf.models[1]); gp_bifs_aa_model_del(pmf.models[2]); gp_bifs_aa_model_del(pmf.dir_model); gp_bifs_aa_dec_del(pmf.dec); return e; }