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 "quant.h"
27 
28 #ifndef GPAC_DISABLE_BIFS
29 
30 #include <math.h>
31 
gf_bifs_dec_qp14_get_bits(GF_BifsDecoder * codec)32 u32 gf_bifs_dec_qp14_get_bits(GF_BifsDecoder *codec)
33 {
34 	if (!codec->ActiveQP || !codec->coord_stored) return 0;
35 	return (u32) ceil(log1p(codec->NumCoord) / log(2) );
36 }
37 
gf_bifs_dec_qp14_enter(GF_BifsDecoder * codec,Bool Enter)38 void gf_bifs_dec_qp14_enter(GF_BifsDecoder * codec, Bool Enter)
39 {
40 	if (!codec->ActiveQP) return;
41 	if (Enter) codec->storing_coord = GF_TRUE;
42 	else {
43 		if (codec->storing_coord) codec->coord_stored = GF_TRUE;
44 		codec->storing_coord = GF_FALSE;
45 	}
46 }
47 
gf_bifs_dec_qp14_reset(GF_BifsDecoder * codec)48 void gf_bifs_dec_qp14_reset(GF_BifsDecoder * codec)
49 {
50 	codec->coord_stored = GF_FALSE;
51 	codec->storing_coord = GF_FALSE;
52 	codec->NumCoord = 0;
53 }
54 
gf_bifs_dec_qp14_set_length(GF_BifsDecoder * codec,u32 NbElements)55 void gf_bifs_dec_qp14_set_length(GF_BifsDecoder * codec, u32 NbElements)
56 {
57 	if (!codec->ActiveQP || !codec->storing_coord || codec->coord_stored) return;
58 	codec->NumCoord = NbElements;
59 }
60 
gf_bifs_dec_qp_set(GF_BifsDecoder * codec,GF_Node * qp)61 GF_Err gf_bifs_dec_qp_set(GF_BifsDecoder *codec, GF_Node *qp)
62 {
63 	assert(gf_node_get_tag(qp) == TAG_MPEG4_QuantizationParameter);
64 
65 	/*if we have an active QP, push it into the stack*/
66 	if (codec->ActiveQP && ((GF_Node*)codec->ActiveQP != codec->scenegraph->global_qp) )
67 		gf_list_insert(codec->QPs, codec->ActiveQP, 0);
68 
69 	codec->ActiveQP = (M_QuantizationParameter *)qp;
70 	return GF_OK;
71 }
72 
gf_bifs_dec_qp_remove(GF_BifsDecoder * codec,Bool ActivatePrev)73 GF_Err gf_bifs_dec_qp_remove(GF_BifsDecoder *codec, Bool ActivatePrev)
74 {
75 	if (!codec->force_keep_qp && codec->ActiveQP && ((GF_Node*)codec->ActiveQP != codec->scenegraph->global_qp) ) {
76 		gf_node_unregister((GF_Node *) codec->ActiveQP, NULL);
77 	}
78 	codec->ActiveQP = NULL;
79 	if (!ActivatePrev) return GF_OK;
80 
81 	if (gf_list_count(codec->QPs)) {
82 		codec->ActiveQP = (M_QuantizationParameter*)gf_list_get(codec->QPs, 0);
83 		gf_list_rem(codec->QPs, 0);
84 	} else if (codec->scenegraph->global_qp) {
85 		codec->ActiveQP = (M_QuantizationParameter *)codec->scenegraph->global_qp;
86 	}
87 	return GF_OK;
88 }
89 
90 //parses efficient float
gf_bifs_dec_mantissa_float(GF_BifsDecoder * codec,GF_BitStream * bs)91 Fixed gf_bifs_dec_mantissa_float(GF_BifsDecoder *codec, GF_BitStream *bs)
92 {
93 	u32 mantLength, expLength, mantSign, mantissa;
94 	unsigned char exp;
95 
96 	union {
97 		Float f;
98 		long l;
99 	} ft_value;
100 
101 	mantLength = gf_bs_read_int(bs, 4);
102 	if (!mantLength) return 0;
103 
104 	expLength = gf_bs_read_int(bs, 3);
105 	mantSign = gf_bs_read_int(bs, 1);
106 	mantissa = gf_bs_read_int(bs, mantLength - 1);
107 
108 	exp = 127;
109 	if (expLength) {
110 		u32 expSign = gf_bs_read_int(bs, 1);
111 		u32 exponent = gf_bs_read_int(bs, expLength-1);
112 		exp += (1-2*expSign)*( (1 << (expLength-1) ) + exponent);
113 	}
114 
115 	ft_value.l = mantSign << 31;
116 	ft_value.l |= (exp & 0xff) << 23;
117 	ft_value.l |= mantissa << 9;
118 	return FLT2FIX(ft_value.f);
119 }
120 
121 //check if the quant type is on in the QP, and if so retrieves NbBits and Min Max
122 //specified for the field
Q_IsTypeOn(M_QuantizationParameter * qp,u32 q_type,u32 * NbBits,SFVec3f * b_min,SFVec3f * b_max)123 Bool Q_IsTypeOn(M_QuantizationParameter *qp, u32 q_type, u32 *NbBits, SFVec3f *b_min, SFVec3f *b_max)
124 {
125 	switch (q_type) {
126 	case QC_3DPOS:
127 		if (!qp->position3DQuant) return GF_FALSE;
128 		*NbBits = qp->position3DNbBits;
129 		b_min->x = MAX(b_min->x, qp->position3DMin.x);
130 		b_min->y = MAX(b_min->y, qp->position3DMin.y);
131 		b_min->z = MAX(b_min->z, qp->position3DMin.z);
132 		b_max->x = MIN(b_max->x, qp->position3DMax.x);
133 		b_max->y = MIN(b_max->y, qp->position3DMax.y);
134 		b_max->z = MIN(b_max->z, qp->position3DMax.z);
135 		return GF_TRUE;
136 	case QC_2DPOS:
137 		if (!qp->position2DQuant) return GF_FALSE;
138 		*NbBits = qp->position2DNbBits;
139 		b_min->x = MAX(b_min->x, qp->position2DMin.x);
140 		b_min->y = MAX(b_min->y, qp->position2DMin.y);
141 		b_max->x = MIN(b_max->x, qp->position2DMax.x);
142 		b_max->y = MIN(b_max->y, qp->position2DMax.y);
143 		return GF_TRUE;
144 	case QC_ORDER:
145 		if (!qp->drawOrderQuant) return GF_FALSE;
146 		*NbBits = qp->drawOrderNbBits;
147 		b_min->x = MAX(b_min->x, qp->drawOrderMin);
148 		b_max->x = MIN(b_max->x, qp->drawOrderMax);
149 		return GF_TRUE;
150 	case QC_COLOR:
151 		if (!qp->colorQuant) return GF_FALSE;
152 		*NbBits = qp->colorNbBits;
153 		b_min->x = b_min->y = b_min->z = MAX(b_min->x, qp->colorMin);
154 		b_max->x = b_max->y = b_max->z = MIN(b_max->x, qp->colorMax);
155 		return GF_TRUE;
156 	case QC_TEXTURE_COORD:
157 		if (!qp->textureCoordinateQuant) return GF_FALSE;
158 		*NbBits = qp->textureCoordinateNbBits;
159 		b_min->x = b_min->y = b_min->z = MAX(b_min->x, qp->textureCoordinateMin);
160 		b_max->x = b_max->y = b_max->z = MIN(b_max->x, qp->textureCoordinateMax);
161 		return GF_TRUE;
162 	case QC_ANGLE:
163 		if (!qp->angleQuant) return GF_FALSE;
164 		*NbBits = qp->angleNbBits;
165 		b_min->x = b_min->y = b_min->z = MAX(b_min->x, qp->angleMin);
166 		b_max->x = b_max->y = b_max->z = MIN(b_max->x, qp->angleMax);
167 		return GF_TRUE;
168 	case QC_SCALE:
169 		if (!qp->scaleQuant) return GF_FALSE;
170 		*NbBits = qp->scaleNbBits;
171 		b_min->x = b_min->y = b_min->z = MAX(b_min->x, qp->scaleMin);
172 		b_max->x = b_max->y = b_max->z = MIN(b_max->x, qp->scaleMax);
173 		return GF_TRUE;
174 	case QC_INTERPOL_KEYS:
175 		if (!qp->keyQuant) return GF_FALSE;
176 		*NbBits = qp->keyNbBits;
177 		b_min->x = MAX(b_min->x, qp->keyMin);
178 		b_min->y = MAX(b_min->y, qp->keyMin);
179 		b_min->z = MAX(b_min->z, qp->keyMin);
180 		b_max->x = MIN(b_max->x, qp->keyMax);
181 		b_max->y = MIN(b_max->y, qp->keyMax);
182 		b_max->z = MIN(b_max->z, qp->keyMax);
183 		return GF_TRUE;
184 	case QC_NORMALS:
185 		if (!qp->normalQuant) return GF_FALSE;
186 		*NbBits = qp->normalNbBits;
187 		b_min->x = b_min->y = b_min->z = 0;
188 		b_max->x = b_max->y = b_max->z = FIX_ONE;
189 		return GF_TRUE;
190 	case QC_ROTATION:
191 		if (!qp->normalQuant) return GF_FALSE;
192 		*NbBits = qp->normalNbBits;
193 		b_min->x = b_min->y = b_min->z = 0;
194 		b_max->x = b_max->y = b_max->z = FIX_ONE;
195 		return GF_TRUE;
196 	case QC_SIZE_3D:
197 		if (!qp->sizeQuant) return GF_FALSE;
198 		*NbBits = qp->sizeNbBits;
199 		b_min->x = b_min->y = b_min->z = MAX(b_min->x, qp->sizeMin);
200 		b_max->x = b_max->y = b_max->z = MIN(b_max->x, qp->sizeMax);
201 		return GF_TRUE;
202 	case QC_SIZE_2D:
203 		if (!qp->sizeQuant) return GF_FALSE;
204 		*NbBits = qp->sizeNbBits;
205 		b_min->x = b_min->y = b_min->z = MAX(b_min->x, qp->sizeMin);
206 		b_max->x = b_max->y = b_max->z = MIN(b_max->x, qp->sizeMax);
207 		return GF_TRUE;
208 
209 	//cf specs, from here ALWAYS ON
210 	case QC_LINEAR_SCALAR:
211 		//nbBits is the one from the FCT - DO NOT CHANGE IT
212 		return GF_TRUE;
213 	case QC_COORD_INDEX:
214 		//nbBits has to be recomputed on the fly
215 		return GF_TRUE;
216 	case QC_RESERVED:
217 		*NbBits = 0;
218 		return GF_TRUE;
219 	default:
220 		return GF_FALSE;
221 	}
222 }
223 
224 
225 //Linear inverse Quantization for floats
Q_InverseQuantize(Fixed Min,Fixed Max,u32 NbBits,u32 value)226 Fixed Q_InverseQuantize(Fixed Min, Fixed Max, u32 NbBits, u32 value)
227 {
228 	if (!value) return Min;
229 	if (value == (u32) ((1 << NbBits) - 1) ) return Max;
230 	return Min + gf_muldiv(Max - Min, INT2FIX(value), INT2FIX( (1 << NbBits) - 1) );
231 }
232 
233 
Q_DecFloat(GF_BifsDecoder * codec,GF_BitStream * bs,u32 FieldType,SFVec3f BMin,SFVec3f BMax,u32 NbBits,void * field_ptr)234 GF_Err Q_DecFloat(GF_BifsDecoder *codec, GF_BitStream *bs, u32 FieldType, SFVec3f BMin, SFVec3f BMax, u32 NbBits, void *field_ptr)
235 {
236 	switch (FieldType) {
237 	case GF_SG_VRML_SFINT32:
238 		return GF_NON_COMPLIANT_BITSTREAM;
239 	case GF_SG_VRML_SFFLOAT:
240 		*((SFFloat *)field_ptr) = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits));
241 		return GF_OK;
242 	case GF_SG_VRML_SFVEC2F:
243 		((SFVec2f *)field_ptr)->x = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits));
244 		((SFVec2f *)field_ptr)->y = Q_InverseQuantize(BMin.y, BMax.y, NbBits, gf_bs_read_int(bs, NbBits));
245 		return GF_OK;
246 	case GF_SG_VRML_SFVEC3F:
247 		((SFVec3f *)field_ptr)->x = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits));
248 		((SFVec3f *)field_ptr)->y = Q_InverseQuantize(BMin.y, BMax.y, NbBits, gf_bs_read_int(bs, NbBits));
249 		((SFVec3f *)field_ptr)->z = Q_InverseQuantize(BMin.z, BMax.z, NbBits, gf_bs_read_int(bs, NbBits));
250 		return GF_OK;
251 	case GF_SG_VRML_SFCOLOR:
252 		((SFColor *)field_ptr)->red = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits));
253 		((SFColor *)field_ptr)->green = Q_InverseQuantize(BMin.y, BMax.y, NbBits, gf_bs_read_int(bs, NbBits));
254 		((SFColor *)field_ptr)->blue = Q_InverseQuantize(BMin.z, BMax.z, NbBits, gf_bs_read_int(bs, NbBits));
255 		return GF_OK;
256 
257 	case GF_SG_VRML_SFROTATION:
258 		//forbidden in this Q mode
259 		return GF_NON_COMPLIANT_BITSTREAM;
260 	}
261 	return GF_OK;
262 }
263 
264 //int in quant are either Linear Scalar fields or CoordIndex
265 //the quant is just a bitshifting into [0, 2^NbBits-1]
266 //so IntMin + ReadBit(NbBits) = value
Q_DecInt(GF_BifsDecoder * codec,GF_BitStream * bs,u32 QType,SFInt32 b_min,u32 NbBits,void * field_ptr)267 GF_Err Q_DecInt(GF_BifsDecoder *codec, GF_BitStream *bs, u32 QType, SFInt32 b_min, u32 NbBits, void *field_ptr)
268 {
269 	switch (QType) {
270 	case QC_LINEAR_SCALAR:
271 	case QC_COORD_INDEX:
272 		*((SFInt32 *)field_ptr) = gf_bs_read_int(bs, NbBits) + b_min;
273 		return GF_OK;
274 	default:
275 		return GF_NON_COMPLIANT_BITSTREAM;
276 	}
277 }
278 
279 //SFRotation and SFVec3f are quantized as normalized vectors ,mapped on a cube
280 //in the UnitSphere (R=1.0)
Q_DecCoordOnUnitSphere(GF_BifsDecoder * codec,GF_BitStream * bs,u32 NbBits,u32 NbComp,Fixed * m_ft)281 GF_Err Q_DecCoordOnUnitSphere(GF_BifsDecoder *codec, GF_BitStream *bs, u32 NbBits, u32 NbComp, Fixed *m_ft)
282 {
283 	u32 i, orient, sign;
284 	s32 value;
285 	Fixed tang[4], delta;
286 	s32 dir;
287 
288 	if (NbComp != 2 && NbComp != 3) return GF_BAD_PARAM;
289 
290 	//only 2 or 3 comp in the quantized version
291 	dir = 1;
292 	if(NbComp == 2) dir -= 2 * gf_bs_read_int(bs, 1);
293 
294 	orient = gf_bs_read_int(bs, 2);
295 
296 	for(i=0; i<NbComp; i++) {
297 		value = gf_bs_read_int(bs, NbBits) - (1 << (NbBits-1) );
298 		sign = (value >= 0) ? 1 : -1;
299 		m_ft[i] = sign * Q_InverseQuantize(0, 1, NbBits-1, sign*value);
300 	}
301 	delta = 1;
302 	for (i=0; i<NbComp; i++) {
303 		tang[i] = gf_tan(gf_mulfix(GF_PI/4, m_ft[i]) );
304 		delta += gf_mulfix(tang[i], tang[i]);
305 	}
306 	delta = gf_divfix(INT2FIX(dir), gf_sqrt(delta) );
307 	m_ft[orient] = delta;
308 
309 	for (i=0; i<NbComp; i++) {
310 		m_ft[ (orient + i+1) % (NbComp+1) ] = gf_mulfix(tang[i], delta);
311 	}
312 	return GF_OK;
313 }
314 
315 //parses a rotation
Q_DecRotation(GF_BifsDecoder * codec,GF_BitStream * bs,u32 NbBits,void * field_ptr)316 GF_Err Q_DecRotation(GF_BifsDecoder *codec, GF_BitStream *bs, u32 NbBits, void *field_ptr)
317 {
318 	u32 i;
319 	Fixed q, sin2, comp[4];
320 	GF_Err e;
321 
322 	e = Q_DecCoordOnUnitSphere(codec, bs, NbBits, 3, comp);
323 	if (e) return e;
324 
325 	q = 2 * gf_acos(comp[0]);
326 	sin2 = gf_sin(q / 2);
327 
328 	if (ABS(sin2) <= FIX_EPSILON) {
329 		for (i=1; i<4; i++) comp[i] = 0;
330 		comp[3] = FIX_ONE;
331 	} else {
332 		for (i=1; i<4; i++) comp[i] = gf_divfix(comp[i], sin2);
333 	}
334 	((SFRotation *)field_ptr)->x = comp[1];
335 	((SFRotation *)field_ptr)->y = comp[2];
336 	((SFRotation *)field_ptr)->z = comp[3];
337 	((SFRotation *)field_ptr)->q = q;
338 	return GF_OK;
339 }
340 
341 //parses a Normal vec
Q_DecNormal(GF_BifsDecoder * codec,GF_BitStream * bs,u32 NbBits,void * field_ptr)342 GF_Err Q_DecNormal(GF_BifsDecoder *codec, GF_BitStream *bs, u32 NbBits, void *field_ptr)
343 {
344 	Fixed comp[3];
345 	SFVec3f v;
346 	GF_Err e;
347 	e = Q_DecCoordOnUnitSphere(codec, bs, NbBits, 2, comp);
348 	if (e) return e;
349 	v.x = comp[0];
350 	v.y = comp[1];
351 	v.z = comp[2];
352 	gf_vec_norm(&v);
353 	*((SFVec3f *)field_ptr) = v;
354 	return GF_OK;
355 }
356 
gf_bifs_dec_unquant_field(GF_BifsDecoder * codec,GF_BitStream * bs,GF_Node * node,GF_FieldInfo * field)357 GF_Err gf_bifs_dec_unquant_field(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
358 {
359 	Bool HasQ;
360 	u8 QType, AType;
361 	u32 NbBits;
362 	Fixed b_min, b_max;
363 	SFVec3f BMin, BMax;
364 	GF_Err e;
365 
366 	/*check QP*/
367 	if (!codec->ActiveQP) return GF_EOS;
368 	/*check FieldType*/
369 	switch (field->fieldType) {
370 	case GF_SG_VRML_SFINT32:
371 	case GF_SG_VRML_SFFLOAT:
372 	case GF_SG_VRML_SFROTATION:
373 	case GF_SG_VRML_SFVEC2F:
374 	case GF_SG_VRML_SFVEC3F:
375 		break;
376 	case GF_SG_VRML_SFCOLOR:
377 		break;
378 	default:
379 		return GF_EOS;
380 	}
381 
382 	/*check NDT*/
383 	HasQ = gf_bifs_get_aq_info(node, field->fieldIndex, &QType, &AType, &b_min, &b_max, &NbBits);
384 	if (!HasQ || !QType) return GF_EOS;
385 
386 	/*get NbBits for QP14 (QC_COORD_INDEX)*/
387 	if (QType == QC_COORD_INDEX) {
388 		NbBits = gf_bifs_dec_qp14_get_bits(codec);
389 		/*QP14 is always on, not having NbBits set means the coord field is set after the index field, hence not decodable*/
390 		if (!NbBits) return GF_NON_COMPLIANT_BITSTREAM;
391 	}
392 
393 	BMin.x = BMin.y = BMin.z = b_min;
394 	BMax.x = BMax.y = BMax.z = b_max;
395 
396 	/*check is the QP is on and retrieves the bounds*/
397 	if (!Q_IsTypeOn(codec->ActiveQP, QType, &NbBits, &BMin, &BMax)) return GF_EOS;
398 
399 	/*ok the field is Quantized, dequantize*/
400 	switch (QType) {
401 	//these are all SFFloat quantized on n fields
402 	case QC_3DPOS:
403 	case QC_2DPOS:
404 	case QC_ORDER:
405 	case QC_COLOR:
406 	case QC_TEXTURE_COORD:
407 	case QC_ANGLE:
408 	case QC_SCALE:
409 	case QC_INTERPOL_KEYS:
410 	case QC_SIZE_3D:
411 	case QC_SIZE_2D:
412 		e = Q_DecFloat(codec, bs, field->fieldType, BMin, BMax, NbBits, field->far_ptr);
413 		break;
414 	//SFInt types
415 	case QC_LINEAR_SCALAR:
416 	case QC_COORD_INDEX:
417 		e = Q_DecInt(codec, bs, QType, (SFInt32) b_min, NbBits, field->far_ptr);
418 		break;
419 	//normalized fields (normals and vectors)
420 	case QC_NORMALS:
421 		//normal quant is only for SFVec3F
422 		if (field->fieldType != GF_SG_VRML_SFVEC3F) return GF_NON_COMPLIANT_BITSTREAM;
423 		e = Q_DecNormal(codec, bs, NbBits, field->far_ptr);
424 		break;
425 	case QC_ROTATION:
426 		//normal quant is only for SFRotation
427 		if (field->fieldType != GF_SG_VRML_SFROTATION) return GF_NON_COMPLIANT_BITSTREAM;
428 		e = Q_DecRotation(codec, bs, NbBits, field->far_ptr);
429 		break;
430 	default:
431 		return GF_BAD_PARAM;
432 	}
433 
434 	if (e) return e;
435 	return GF_OK;
436 }
437 
438 #endif /*GPAC_DISABLE_BIFS*/
439