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 
gf_bifs_enc_qp_set(GF_BifsEncoder * codec,GF_Node * qp)31 GF_Err gf_bifs_enc_qp_set(GF_BifsEncoder *codec, GF_Node *qp)
32 {
33 	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 	if (codec->ActiveQP && ((GF_Node*)codec->ActiveQP != codec->scene_graph->global_qp) )
37 		gf_list_insert(codec->QPs, codec->ActiveQP, 0);
38 
39 	codec->ActiveQP = (M_QuantizationParameter *)qp;
40 	return GF_OK;
41 }
42 
gf_bifs_enc_qp_remove(GF_BifsEncoder * codec,Bool ActivatePrev)43 GF_Err gf_bifs_enc_qp_remove(GF_BifsEncoder *codec, Bool ActivatePrev)
44 {
45 	codec->ActiveQP = NULL;
46 	if (!ActivatePrev) return GF_OK;
47 
48 	if (gf_list_count(codec->QPs)) {
49 		codec->ActiveQP = (M_QuantizationParameter*)gf_list_get(codec->QPs, 0);
50 		gf_list_rem(codec->QPs, 0);
51 	} else if (codec->scene_graph->global_qp) {
52 		codec->ActiveQP = (M_QuantizationParameter *)codec->scene_graph->global_qp;
53 	}
54 	return GF_OK;
55 }
56 
57 
gf_bifs_enc_qp14_get_bits(GF_BifsEncoder * codec)58 u32 gf_bifs_enc_qp14_get_bits(GF_BifsEncoder *codec)
59 {
60 	if (!codec->ActiveQP || !codec->coord_stored) return 0;
61 	return (u32) ceil(log1p(codec->NumCoord) / log(2) );
62 }
63 
gf_bifs_enc_qp14_enter(GF_BifsEncoder * codec,Bool Enter)64 void gf_bifs_enc_qp14_enter(GF_BifsEncoder *codec, Bool Enter)
65 {
66 	if (!codec->ActiveQP) return;
67 	if (Enter) codec->storing_coord = GF_TRUE;
68 	else {
69 		if (codec->storing_coord) codec->coord_stored = GF_TRUE;
70 		codec->storing_coord = GF_FALSE;
71 	}
72 }
73 
gf_bifs_enc_qp14_reset(GF_BifsEncoder * codec)74 void gf_bifs_enc_qp14_reset(GF_BifsEncoder *codec)
75 {
76 	codec->coord_stored = GF_FALSE;
77 	codec->storing_coord = GF_FALSE;
78 	codec->NumCoord = 0;
79 }
80 
gf_bifs_enc_qp14_set_length(GF_BifsEncoder * codec,u32 NbElements)81 void gf_bifs_enc_qp14_set_length(GF_BifsEncoder *codec, u32 NbElements)
82 {
83 	if (!codec->ActiveQP || !codec->storing_coord || codec->coord_stored) return;
84 	codec->NumCoord = NbElements;
85 }
86 
gf_bifs_enc_mantissa_float(GF_BifsEncoder * codec,Fixed ft,GF_BitStream * bs)87 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 	if (ft == 0) {
99 		gf_bs_write_int(bs, 0, 4);
100 		return;
101 	}
102 	ft_val.f = FIX2FLT(ft);
103 
104 	mantSign = ((ft_val.l & 0x80000000) >> 31) & 0x1;
105 	mantissa = (ft_val.l & 0x007FFFFF) >> 9;
106 	mantLength = 15;
107 	expSign=0;
108 	exp =(((ft_val.l & 0x7F800000) >> 23)-127);
109 	expLength = 8;
110 
111 	if (mantissa == 0) mantLength = 1;
112 
113 
114 	if (exp) {
115 		if (exp< 0) {
116 			expSign = 1;
117 			exp = -exp;
118 		}
119 		while ((exp & (1<<(--expLength)))==0) { }
120 		exp &= ~(1<<expLength);
121 		expLength++;
122 	} else {
123 		expLength=0;
124 	}
125 
126 	nbBits=0;
127 	for(i = mantissa; i>0; ++nbBits) i >>= 1;
128 
129 	gf_bs_write_int(bs, nbBits+1, 4);
130 	if (mantLength) {
131 		gf_bs_write_int(bs, expLength, 3);
132 		gf_bs_write_int(bs, mantSign, 1);
133 		gf_bs_write_int(bs, mantissa, nbBits);
134 		if(expLength) {
135 			gf_bs_write_int(bs, expSign, 1);
136 			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...
Q_Quantize(Fixed Min,Fixed Max,u32 NbBits,Fixed value)143 s32 Q_Quantize(Fixed Min, Fixed Max, u32 NbBits, Fixed value)
144 {
145 	Float _v;
146 	if (value <= Min) return 0;
147 	if (value >= Max) return (1<<NbBits)-1;
148 	_v = FIX2FLT(value - Min);
149 	_v *= (1 << NbBits) - 1;
150 	_v /= FIX2FLT(Max - Min);
151 	return FIX2INT(gf_floor( FLT2FIX(_v+0.5) ) );
152 }
153 
154 
Q_EncFloat(GF_BifsEncoder * codec,GF_BitStream * bs,u32 FieldType,SFVec3f BMin,SFVec3f BMax,u32 NbBits,void * field_ptr)155 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 	switch (FieldType) {
159 	case GF_SG_VRML_SFINT32:
160 		return GF_NON_COMPLIANT_BITSTREAM;
161 	case GF_SG_VRML_SFFLOAT:
162 		newVal = Q_Quantize(BMin.x, BMax.x, NbBits, *((SFFloat *)field_ptr));
163 		gf_bs_write_int(bs, newVal, NbBits);
164 		return GF_OK;
165 	case GF_SG_VRML_SFVEC2F:
166 		newVal = Q_Quantize(BMin.x, BMax.x, NbBits, ((SFVec2f *)field_ptr)->x);
167 		gf_bs_write_int(bs, newVal, NbBits);
168 		newVal = Q_Quantize(BMin.y, BMax.y, NbBits, ((SFVec2f *)field_ptr)->y);
169 		gf_bs_write_int(bs, newVal, NbBits);
170 		return GF_OK;
171 	case GF_SG_VRML_SFVEC3F:
172 		newVal = Q_Quantize(BMin.x, BMax.x, NbBits, ((SFVec3f *)field_ptr)->x);
173 		gf_bs_write_int(bs, newVal, NbBits);
174 		newVal = Q_Quantize(BMin.y, BMax.y, NbBits, ((SFVec3f *)field_ptr)->y);
175 		gf_bs_write_int(bs, newVal, NbBits);
176 		newVal = Q_Quantize(BMin.z, BMax.z, NbBits, ((SFVec3f *)field_ptr)->z);
177 		gf_bs_write_int(bs, newVal, NbBits);
178 		return GF_OK;
179 	case GF_SG_VRML_SFCOLOR:
180 		newVal = Q_Quantize(BMin.x, BMax.x, NbBits, ((SFColor *)field_ptr)->red);
181 		gf_bs_write_int(bs, newVal, NbBits);
182 		newVal = Q_Quantize(BMin.y, BMax.y, NbBits, ((SFColor *)field_ptr)->green);
183 		gf_bs_write_int(bs, newVal, NbBits);
184 		newVal = Q_Quantize(BMin.z, BMax.z, NbBits, ((SFColor *)field_ptr)->blue);
185 		gf_bs_write_int(bs, newVal, NbBits);
186 		return GF_OK;
187 
188 	case GF_SG_VRML_SFROTATION:
189 		//forbidden in this Q mode
190 		return GF_NON_COMPLIANT_BITSTREAM;
191 	}
192 	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
Q_EncInt(GF_BifsEncoder * codec,GF_BitStream * bs,u32 QType,SFInt32 b_min,u32 NbBits,void * field_ptr)198 GF_Err Q_EncInt(GF_BifsEncoder *codec, GF_BitStream *bs, u32 QType, SFInt32 b_min, u32 NbBits, void *field_ptr)
199 {
200 	switch (QType) {
201 	case QC_LINEAR_SCALAR:
202 	case QC_COORD_INDEX:
203 		gf_bs_write_int(bs, *((SFInt32 *)field_ptr) - b_min, NbBits);
204 		return GF_OK;
205 	default:
206 		return GF_NON_COMPLIANT_BITSTREAM;
207 	}
208 }
209 
Q_EncCoordOnUnitSphere(GF_BifsEncoder * codec,GF_BitStream * bs,u32 NbBits,u32 NbComp,Fixed * m_ft)210 GF_Err Q_EncCoordOnUnitSphere(GF_BifsEncoder *codec, GF_BitStream *bs, u32 NbBits, u32 NbComp, Fixed *m_ft)
211 {
212 	u32 i;
213 	u32 len = NbComp+1;
214 	u32 orientation=0;
215 	Fixed maxTmp = - FIX_MAX;
216 	for (i=0; i<len; i++) {
217 		if (ABS(m_ft[i]) > maxTmp) {
218 			maxTmp = ABS(m_ft[i]);
219 			orientation = i;
220 		}
221 	}
222 	if(NbComp==2) gf_bs_write_int(bs, ((m_ft[orientation]>0) ? 0 : 1), 1);
223 	gf_bs_write_int(bs, orientation, 2);
224 	for (i=0; i<NbComp; i++) {
225 		Fixed v = gf_mulfix(gf_divfix(INT2FIX(4), GF_PI) , gf_atan2(m_ft[orientation], m_ft[(orientation+i+1) % len]));
226 		s32 qdt = Q_Quantize(0, 1, NbBits-1, (v>=0 ? v : -v));
227 		s32 qv = (1<<(NbBits-1)) + (v>=0 ? 1 : -1) * qdt;
228 		gf_bs_write_int(bs, qv, NbBits);
229 	}
230 	return GF_OK;
231 }
232 
Q_EncNormal(GF_BifsEncoder * codec,GF_BitStream * bs,u32 NbBits,void * field_ptr)233 GF_Err Q_EncNormal(GF_BifsEncoder *codec, GF_BitStream *bs, u32 NbBits, void *field_ptr)
234 {
235 	Fixed comp[3];
236 	SFVec3f v =  * (SFVec3f *)field_ptr;
237 	gf_vec_norm(&v);
238 	comp[0] = v.x;
239 	comp[1] = v.y;
240 	comp[2] = v.z;
241 	return Q_EncCoordOnUnitSphere(codec, bs, NbBits, 2, comp);
242 }
243 
Q_EncRotation(GF_BifsEncoder * codec,GF_BitStream * bs,u32 NbBits,void * field_ptr)244 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 	quat = gf_quat_from_rotation(*(SFRotation *)field_ptr);
251 	comp[0] = quat.q;
252 	comp[1] = quat.x;
253 	comp[2] = quat.y;
254 	comp[3] = quat.z;
255 	return Q_EncCoordOnUnitSphere(codec, bs, NbBits, 3, comp);
256 }
257 
gf_bifs_enc_quant_field(GF_BifsEncoder * codec,GF_BitStream * bs,GF_Node * node,GF_FieldInfo * field)258 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 	if (!codec->ActiveQP) return GF_EOS;
269 	/*check FieldType*/
270 	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 	HasQ = gf_bifs_get_aq_info(node, field->fieldIndex, &QType, &AType, &b_min, &b_max, &NbBits);
285 	if (!HasQ || !QType) return GF_EOS;
286 
287 	/*get NbBits for QP14 (QC_COORD_INDEX)*/
288 	if (QType == QC_COORD_INDEX) {
289 		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 		if (!NbBits)
292 			return GF_NON_COMPLIANT_BITSTREAM;
293 	}
294 
295 	BMin.x = BMin.y = BMin.z = b_min;
296 	BMax.x = BMax.y = BMax.z = b_max;
297 
298 	/*check is the QP is on and retrieves the bounds*/
299 	if (!Q_IsTypeOn(codec->ActiveQP, QType, &NbBits, &BMin, &BMax)) return GF_EOS;
300 
301 	/*ok the field is Quantized, dequantize*/
302 	switch (QType) {
303 	//these are all SFFloat quantized on n fields
304 	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 		e = Q_EncFloat(codec, bs, field->fieldType, BMin, BMax, NbBits, field->far_ptr);
315 		break;
316 	//SFInt types
317 	case QC_LINEAR_SCALAR:
318 	case QC_COORD_INDEX:
319 		e = Q_EncInt(codec, bs, QType, (SFInt32) b_min, NbBits, field->far_ptr);
320 		break;
321 	//normalized fields (normals and vectors)
322 	case QC_NORMALS:
323 		//normal quant is only for SFVec3F
324 		if (field->fieldType != GF_SG_VRML_SFVEC3F) return GF_NON_COMPLIANT_BITSTREAM;
325 		e = Q_EncNormal(codec, bs, NbBits, field->far_ptr);
326 		break;
327 	case QC_ROTATION:
328 		//normal quant is only for SFVec3F
329 		if (field->fieldType != GF_SG_VRML_SFROTATION) return GF_NON_COMPLIANT_BITSTREAM;
330 		e = Q_EncRotation(codec, bs, NbBits, field->far_ptr);
331 		break;
332 	default:
333 		return GF_BAD_PARAM;
334 	}
335 	return e;
336 }
337 
338 #endif	/*GPAC_DISABLE_BIFS_ENC*/
339