LCOV - code coverage report
Current view: top level - bifs - quantize.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 135 143 94.4 %
Date: 2021-04-29 23:48:07 Functions: 13 14 92.9 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2012
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / BIFS codec sub-project
       9             :  *
      10             :  *  GPAC is free software; you can redistribute it and/or modify
      11             :  *  it under the terms of the GNU Lesser General Public License as published by
      12             :  *  the Free Software Foundation; either version 2, or (at your option)
      13             :  *  any later version.
      14             :  *
      15             :  *  GPAC is distributed in the hope that it will be useful,
      16             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  *  GNU Lesser General Public License for more details.
      19             :  *
      20             :  *  You should have received a copy of the GNU Lesser General Public
      21             :  *  License along with this library; see the file COPYING.  If not, write to
      22             :  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23             :  *
      24             :  */
      25             : 
      26             : #include "math.h"
      27             : #include "quant.h"
      28             : 
      29             : #ifndef GPAC_DISABLE_BIFS_ENC
      30             : 
      31          49 : GF_Err gf_bifs_enc_qp_set(GF_BifsEncoder *codec, GF_Node *qp)
      32             : {
      33          49 :         if (gf_node_get_tag(qp) != TAG_MPEG4_QuantizationParameter) return GF_BAD_PARAM;
      34             : 
      35             :         /*if we have an active QP, push it into the stack*/
      36          49 :         if (codec->ActiveQP && ((GF_Node*)codec->ActiveQP != codec->scene_graph->global_qp) )
      37           0 :                 gf_list_insert(codec->QPs, codec->ActiveQP, 0);
      38             : 
      39          49 :         codec->ActiveQP = (M_QuantizationParameter *)qp;
      40          49 :         return GF_OK;
      41             : }
      42             : 
      43          49 : GF_Err gf_bifs_enc_qp_remove(GF_BifsEncoder *codec, Bool ActivatePrev)
      44             : {
      45          49 :         codec->ActiveQP = NULL;
      46          49 :         if (!ActivatePrev) return GF_OK;
      47             : 
      48           8 :         if (gf_list_count(codec->QPs)) {
      49           0 :                 codec->ActiveQP = (M_QuantizationParameter*)gf_list_get(codec->QPs, 0);
      50           0 :                 gf_list_rem(codec->QPs, 0);
      51           8 :         } else if (codec->scene_graph->global_qp) {
      52           8 :                 codec->ActiveQP = (M_QuantizationParameter *)codec->scene_graph->global_qp;
      53             :         }
      54             :         return GF_OK;
      55             : }
      56             : 
      57             : 
      58         650 : u32 gf_bifs_enc_qp14_get_bits(GF_BifsEncoder *codec)
      59             : {
      60         650 :         if (!codec->ActiveQP || !codec->coord_stored) return 0;
      61         650 :         return (u32) ceil(log1p(codec->NumCoord) / log(2) );
      62             : }
      63             : 
      64        3546 : void gf_bifs_enc_qp14_enter(GF_BifsEncoder *codec, Bool Enter)
      65             : {
      66        3546 :         if (!codec->ActiveQP) return;
      67         232 :         if (Enter) codec->storing_coord = GF_TRUE;
      68             :         else {
      69         116 :                 if (codec->storing_coord) codec->coord_stored = GF_TRUE;
      70         116 :                 codec->storing_coord = GF_FALSE;
      71             :         }
      72             : }
      73             : 
      74         116 : void gf_bifs_enc_qp14_reset(GF_BifsEncoder *codec)
      75             : {
      76         116 :         codec->coord_stored = GF_FALSE;
      77         116 :         codec->storing_coord = GF_FALSE;
      78         116 :         codec->NumCoord = 0;
      79         116 : }
      80             : 
      81        9478 : void gf_bifs_enc_qp14_set_length(GF_BifsEncoder *codec, u32 NbElements)
      82             : {
      83        9478 :         if (!codec->ActiveQP || !codec->storing_coord || codec->coord_stored) return;
      84         116 :         codec->NumCoord = NbElements;
      85             : }
      86             : 
      87         120 : void gf_bifs_enc_mantissa_float(GF_BifsEncoder *codec, Fixed ft, GF_BitStream *bs)
      88             : {
      89             :         u32 mantLength, expLength, mantSign, mantissa, expSign, i, nbBits;
      90             :         s32 exp;
      91             : 
      92             :         union
      93             :         {
      94             :                 Float f;
      95             :                 s32 l;
      96             :         } ft_val;
      97             : 
      98         120 :         if (ft == 0) {
      99           0 :                 gf_bs_write_int(bs, 0, 4);
     100             :                 return;
     101             :         }
     102         120 :         ft_val.f = FIX2FLT(ft);
     103             : 
     104         120 :         mantSign = ((ft_val.l & 0x80000000) >> 31) & 0x1;
     105         120 :         mantissa = (ft_val.l & 0x007FFFFF) >> 9;
     106             :         mantLength = 15;
     107             :         expSign=0;
     108         120 :         exp =(((ft_val.l & 0x7F800000) >> 23)-127);
     109             :         expLength = 8;
     110             : 
     111             :         if (mantissa == 0) mantLength = 1;
     112             : 
     113             : 
     114         120 :         if (exp) {
     115         120 :                 if (exp< 0) {
     116             :                         expSign = 1;
     117           0 :                         exp = -exp;
     118             :                 }
     119         720 :                 while ((exp & (1<<(--expLength)))==0) { }
     120         120 :                 exp &= ~(1<<expLength);
     121             :                 expLength++;
     122             :         } else {
     123             :                 expLength=0;
     124             :         }
     125             : 
     126             :         nbBits=0;
     127         120 :         for(i = mantissa; i>0; ++nbBits) i >>= 1;
     128             : 
     129         120 :         gf_bs_write_int(bs, nbBits+1, 4);
     130             :         if (mantLength) {
     131         120 :                 gf_bs_write_int(bs, expLength, 3);
     132         120 :                 gf_bs_write_int(bs, mantSign, 1);
     133         120 :                 gf_bs_write_int(bs, mantissa, nbBits);
     134         120 :                 if(expLength) {
     135         120 :                         gf_bs_write_int(bs, expSign, 1);
     136         120 :                         gf_bs_write_int(bs, exp, expLength - 1);
     137             :                 }
     138             :         }
     139             : }
     140             : 
     141             : 
     142             : //Linear Quantization for floats - go back to float to avoid overflow if nbBits more than 15...
     143        2786 : s32 Q_Quantize(Fixed Min, Fixed Max, u32 NbBits, Fixed value)
     144             : {
     145             :         Float _v;
     146        2786 :         if (value <= Min) return 0;
     147        2209 :         if (value >= Max) return (1<<NbBits)-1;
     148        1531 :         _v = FIX2FLT(value - Min);
     149        1531 :         _v *= (1 << NbBits) - 1;
     150        1531 :         _v /= FIX2FLT(Max - Min);
     151        1531 :         return FIX2INT(gf_floor( FLT2FIX(_v+0.5) ) );
     152             : }
     153             : 
     154             : 
     155        1211 : GF_Err Q_EncFloat(GF_BifsEncoder *codec, GF_BitStream *bs, u32 FieldType, SFVec3f BMin, SFVec3f BMax, u32 NbBits, void *field_ptr)
     156             : {
     157             :         s32 newVal;
     158        1211 :         switch (FieldType) {
     159             :         case GF_SG_VRML_SFINT32:
     160             :                 return GF_NON_COMPLIANT_BITSTREAM;
     161         192 :         case GF_SG_VRML_SFFLOAT:
     162         192 :                 newVal = Q_Quantize(BMin.x, BMax.x, NbBits, *((SFFloat *)field_ptr));
     163         192 :                 gf_bs_write_int(bs, newVal, NbBits);
     164         192 :                 return GF_OK;
     165         667 :         case GF_SG_VRML_SFVEC2F:
     166         667 :                 newVal = Q_Quantize(BMin.x, BMax.x, NbBits, ((SFVec2f *)field_ptr)->x);
     167         667 :                 gf_bs_write_int(bs, newVal, NbBits);
     168         667 :                 newVal = Q_Quantize(BMin.y, BMax.y, NbBits, ((SFVec2f *)field_ptr)->y);
     169         667 :                 gf_bs_write_int(bs, newVal, NbBits);
     170         667 :                 return GF_OK;
     171          20 :         case GF_SG_VRML_SFVEC3F:
     172          20 :                 newVal = Q_Quantize(BMin.x, BMax.x, NbBits, ((SFVec3f *)field_ptr)->x);
     173          20 :                 gf_bs_write_int(bs, newVal, NbBits);
     174          20 :                 newVal = Q_Quantize(BMin.y, BMax.y, NbBits, ((SFVec3f *)field_ptr)->y);
     175          20 :                 gf_bs_write_int(bs, newVal, NbBits);
     176          20 :                 newVal = Q_Quantize(BMin.z, BMax.z, NbBits, ((SFVec3f *)field_ptr)->z);
     177          20 :                 gf_bs_write_int(bs, newVal, NbBits);
     178          20 :                 return GF_OK;
     179         332 :         case GF_SG_VRML_SFCOLOR:
     180         332 :                 newVal = Q_Quantize(BMin.x, BMax.x, NbBits, ((SFColor *)field_ptr)->red);
     181         332 :                 gf_bs_write_int(bs, newVal, NbBits);
     182         332 :                 newVal = Q_Quantize(BMin.y, BMax.y, NbBits, ((SFColor *)field_ptr)->green);
     183         332 :                 gf_bs_write_int(bs, newVal, NbBits);
     184         332 :                 newVal = Q_Quantize(BMin.z, BMax.z, NbBits, ((SFColor *)field_ptr)->blue);
     185         332 :                 gf_bs_write_int(bs, newVal, NbBits);
     186         332 :                 return GF_OK;
     187             : 
     188             :         case GF_SG_VRML_SFROTATION:
     189             :                 //forbidden in this Q mode
     190             :                 return GF_NON_COMPLIANT_BITSTREAM;
     191             :         }
     192           0 :         return GF_OK;
     193             : }
     194             : 
     195             : //int in quant are either Linear Scalar fields or CoordIndex
     196             : //the quant is just a bitshifting into [0, 2^NbBits-1]
     197             : //so v = value - b_min
     198           0 : GF_Err Q_EncInt(GF_BifsEncoder *codec, GF_BitStream *bs, u32 QType, SFInt32 b_min, u32 NbBits, void *field_ptr)
     199             : {
     200         823 :         switch (QType) {
     201         823 :         case QC_LINEAR_SCALAR:
     202             :         case QC_COORD_INDEX:
     203         823 :                 gf_bs_write_int(bs, *((SFInt32 *)field_ptr) - b_min, NbBits);
     204           0 :                 return GF_OK;
     205             :         default:
     206             :                 return GF_NON_COMPLIANT_BITSTREAM;
     207             :         }
     208             : }
     209             : 
     210          88 : GF_Err Q_EncCoordOnUnitSphere(GF_BifsEncoder *codec, GF_BitStream *bs, u32 NbBits, u32 NbComp, Fixed *m_ft)
     211             : {
     212             :         u32 i;
     213          88 :         u32 len = NbComp+1;
     214             :         u32 orientation=0;
     215             :         Fixed maxTmp = - FIX_MAX;
     216         380 :         for (i=0; i<len; i++) {
     217         292 :                 if (ABS(m_ft[i]) > maxTmp) {
     218         108 :                         maxTmp = ABS(m_ft[i]);
     219             :                         orientation = i;
     220             :                 }
     221             :         }
     222          88 :         if(NbComp==2) gf_bs_write_int(bs, ((m_ft[orientation]>0) ? 0 : 1), 1);
     223          88 :         gf_bs_write_int(bs, orientation, 2);
     224         292 :         for (i=0; i<NbComp; i++) {
     225         204 :                 Fixed v = gf_mulfix(gf_divfix(INT2FIX(4), GF_PI) , gf_atan2(m_ft[orientation], m_ft[(orientation+i+1) % len]));
     226         204 :                 s32 qdt = Q_Quantize(0, 1, NbBits-1, (v>=0 ? v : -v));
     227         204 :                 s32 qv = (1<<(NbBits-1)) + (v>=0 ? 1 : -1) * qdt;
     228         204 :                 gf_bs_write_int(bs, qv, NbBits);
     229             :         }
     230          88 :         return GF_OK;
     231             : }
     232             : 
     233          60 : GF_Err Q_EncNormal(GF_BifsEncoder *codec, GF_BitStream *bs, u32 NbBits, void *field_ptr)
     234             : {
     235             :         Fixed comp[3];
     236          60 :         SFVec3f v =  * (SFVec3f *)field_ptr;
     237          60 :         gf_vec_norm(&v);
     238          60 :         comp[0] = v.x;
     239          60 :         comp[1] = v.y;
     240          60 :         comp[2] = v.z;
     241          60 :         return Q_EncCoordOnUnitSphere(codec, bs, NbBits, 2, comp);
     242             : }
     243             : 
     244          28 : GF_Err Q_EncRotation(GF_BifsEncoder *codec, GF_BitStream *bs, u32 NbBits, void *field_ptr)
     245             : {
     246             :         GF_Vec4 quat;
     247             :         Fixed comp[4];
     248             : 
     249             :         /*get quaternion*/
     250          28 :         quat = gf_quat_from_rotation(*(SFRotation *)field_ptr);
     251          28 :         comp[0] = quat.q;
     252          28 :         comp[1] = quat.x;
     253          28 :         comp[2] = quat.y;
     254          28 :         comp[3] = quat.z;
     255          28 :         return Q_EncCoordOnUnitSphere(codec, bs, NbBits, 3, comp);
     256             : }
     257             : 
     258      151511 : GF_Err gf_bifs_enc_quant_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
     259             : {
     260             :         Bool HasQ;
     261             :         u8 QType, AType;
     262             :         u32 NbBits;
     263             :         Fixed b_min, b_max;
     264             :         SFVec3f BMin, BMax;
     265             :         GF_Err e;
     266             : 
     267             :         /*check QP*/
     268      151511 :         if (!codec->ActiveQP) return GF_EOS;
     269             :         /*check FieldType*/
     270        5370 :         switch (field->fieldType) {
     271             :         case GF_SG_VRML_SFINT32:
     272             :         case GF_SG_VRML_SFFLOAT:
     273             :         case GF_SG_VRML_SFROTATION:
     274             :         case GF_SG_VRML_SFVEC2F:
     275             :         case GF_SG_VRML_SFVEC3F:
     276             :                 break;
     277             :         case GF_SG_VRML_SFCOLOR:
     278             :                 break;
     279             :         default:
     280             :                 return GF_EOS;
     281             :         }
     282             : 
     283             :         /*check NDT*/
     284        4088 :         HasQ = gf_bifs_get_aq_info(node, field->fieldIndex, &QType, &AType, &b_min, &b_max, &NbBits);
     285        4088 :         if (!HasQ || !QType) return GF_EOS;
     286             : 
     287             :         /*get NbBits for QP14 (QC_COORD_INDEX)*/
     288        3839 :         if (QType == QC_COORD_INDEX) {
     289         650 :                 NbBits = gf_bifs_enc_qp14_get_bits(codec);
     290             :                 /*QP14 is always on, not having NbBits set means the coord field is set after the index field, hence not decodable*/
     291         650 :                 if (!NbBits)
     292             :                         return GF_NON_COMPLIANT_BITSTREAM;
     293             :         }
     294             : 
     295        3839 :         BMin.x = BMin.y = BMin.z = b_min;
     296        3839 :         BMax.x = BMax.y = BMax.z = b_max;
     297             : 
     298             :         /*check is the QP is on and retrieves the bounds*/
     299        3839 :         if (!Q_IsTypeOn(codec->ActiveQP, QType, &NbBits, &BMin, &BMax)) return GF_EOS;
     300             : 
     301             :         /*ok the field is Quantized, dequantize*/
     302        2122 :         switch (QType) {
     303             :         //these are all SFFloat quantized on n fields
     304        1211 :         case QC_3DPOS:
     305             :         case QC_2DPOS:
     306             :         case QC_ORDER:
     307             :         case QC_COLOR:
     308             :         case QC_TEXTURE_COORD:
     309             :         case QC_ANGLE:
     310             :         case QC_SCALE:
     311             :         case QC_INTERPOL_KEYS:
     312             :         case QC_SIZE_3D:
     313             :         case QC_SIZE_2D:
     314        1211 :                 e = Q_EncFloat(codec, bs, field->fieldType, BMin, BMax, NbBits, field->far_ptr);
     315        1211 :                 break;
     316             :         //SFInt types
     317         823 :         case QC_LINEAR_SCALAR:
     318             :         case QC_COORD_INDEX:
     319         823 :                 e = Q_EncInt(codec, bs, QType, (SFInt32) b_min, NbBits, field->far_ptr);
     320             :                 break;
     321             :         //normalized fields (normals and vectors)
     322          60 :         case QC_NORMALS:
     323             :                 //normal quant is only for SFVec3F
     324          60 :                 if (field->fieldType != GF_SG_VRML_SFVEC3F) return GF_NON_COMPLIANT_BITSTREAM;
     325          60 :                 e = Q_EncNormal(codec, bs, NbBits, field->far_ptr);
     326          60 :                 break;
     327          28 :         case QC_ROTATION:
     328             :                 //normal quant is only for SFVec3F
     329          28 :                 if (field->fieldType != GF_SG_VRML_SFROTATION) return GF_NON_COMPLIANT_BITSTREAM;
     330          28 :                 e = Q_EncRotation(codec, bs, NbBits, field->far_ptr);
     331          28 :                 break;
     332             :         default:
     333             :                 return GF_BAD_PARAM;
     334             :         }
     335             :         return e;
     336             : }
     337             : 
     338             : #endif  /*GPAC_DISABLE_BIFS_ENC*/

Generated by: LCOV version 1.13