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 "quant.h"
27 :
28 : #ifndef GPAC_DISABLE_BIFS
29 :
30 : #include <math.h>
31 :
32 30 : u32 gf_bifs_dec_qp14_get_bits(GF_BifsDecoder *codec)
33 : {
34 30 : if (!codec->ActiveQP || !codec->coord_stored) return 0;
35 30 : return (u32) ceil(log1p(codec->NumCoord) / log(2) );
36 : }
37 :
38 1234 : void gf_bifs_dec_qp14_enter(GF_BifsDecoder * codec, Bool Enter)
39 : {
40 1234 : if (!codec->ActiveQP) return;
41 120 : if (Enter) codec->storing_coord = GF_TRUE;
42 : else {
43 60 : if (codec->storing_coord) codec->coord_stored = GF_TRUE;
44 60 : codec->storing_coord = GF_FALSE;
45 : }
46 : }
47 :
48 60 : void gf_bifs_dec_qp14_reset(GF_BifsDecoder * codec)
49 : {
50 60 : codec->coord_stored = GF_FALSE;
51 60 : codec->storing_coord = GF_FALSE;
52 60 : codec->NumCoord = 0;
53 60 : }
54 :
55 2390 : void gf_bifs_dec_qp14_set_length(GF_BifsDecoder * codec, u32 NbElements)
56 : {
57 2390 : if (!codec->ActiveQP || !codec->storing_coord || codec->coord_stored) return;
58 60 : codec->NumCoord = NbElements;
59 : }
60 :
61 45 : 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 45 : if (codec->ActiveQP && ((GF_Node*)codec->ActiveQP != codec->scenegraph->global_qp) )
67 0 : gf_list_insert(codec->QPs, codec->ActiveQP, 0);
68 :
69 45 : codec->ActiveQP = (M_QuantizationParameter *)qp;
70 45 : return GF_OK;
71 : }
72 :
73 45 : GF_Err gf_bifs_dec_qp_remove(GF_BifsDecoder *codec, Bool ActivatePrev)
74 : {
75 45 : if (!codec->force_keep_qp && codec->ActiveQP && ((GF_Node*)codec->ActiveQP != codec->scenegraph->global_qp) ) {
76 9 : gf_node_unregister((GF_Node *) codec->ActiveQP, NULL);
77 : }
78 45 : codec->ActiveQP = NULL;
79 45 : if (!ActivatePrev) return GF_OK;
80 :
81 0 : if (gf_list_count(codec->QPs)) {
82 0 : codec->ActiveQP = (M_QuantizationParameter*)gf_list_get(codec->QPs, 0);
83 0 : gf_list_rem(codec->QPs, 0);
84 0 : } else if (codec->scenegraph->global_qp) {
85 0 : codec->ActiveQP = (M_QuantizationParameter *)codec->scenegraph->global_qp;
86 : }
87 : return GF_OK;
88 : }
89 :
90 : //parses efficient float
91 90 : 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 90 : mantLength = gf_bs_read_int(bs, 4);
102 90 : if (!mantLength) return 0;
103 :
104 90 : expLength = gf_bs_read_int(bs, 3);
105 90 : mantSign = gf_bs_read_int(bs, 1);
106 90 : mantissa = gf_bs_read_int(bs, mantLength - 1);
107 :
108 : exp = 127;
109 90 : if (expLength) {
110 90 : u32 expSign = gf_bs_read_int(bs, 1);
111 90 : u32 exponent = gf_bs_read_int(bs, expLength-1);
112 90 : exp += (1-2*expSign)*( (1 << (expLength-1) ) + exponent);
113 : }
114 :
115 90 : ft_value.l = mantSign << 31;
116 90 : ft_value.l |= (exp & 0xff) << 23;
117 90 : ft_value.l |= mantissa << 9;
118 90 : 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
123 4454 : Bool Q_IsTypeOn(M_QuantizationParameter *qp, u32 q_type, u32 *NbBits, SFVec3f *b_min, SFVec3f *b_max)
124 : {
125 4454 : switch (q_type) {
126 323 : case QC_3DPOS:
127 323 : if (!qp->position3DQuant) return GF_FALSE;
128 35 : *NbBits = qp->position3DNbBits;
129 35 : b_min->x = MAX(b_min->x, qp->position3DMin.x);
130 35 : b_min->y = MAX(b_min->y, qp->position3DMin.y);
131 35 : b_min->z = MAX(b_min->z, qp->position3DMin.z);
132 35 : b_max->x = MIN(b_max->x, qp->position3DMax.x);
133 35 : b_max->y = MIN(b_max->y, qp->position3DMax.y);
134 35 : b_max->z = MIN(b_max->z, qp->position3DMax.z);
135 35 : return GF_TRUE;
136 1011 : case QC_2DPOS:
137 1011 : if (!qp->position2DQuant) return GF_FALSE;
138 1011 : *NbBits = qp->position2DNbBits;
139 1011 : b_min->x = MAX(b_min->x, qp->position2DMin.x);
140 1011 : b_min->y = MAX(b_min->y, qp->position2DMin.y);
141 1011 : b_max->x = MIN(b_max->x, qp->position2DMax.x);
142 1011 : b_max->y = MIN(b_max->y, qp->position2DMax.y);
143 1011 : return GF_TRUE;
144 0 : case QC_ORDER:
145 0 : if (!qp->drawOrderQuant) return GF_FALSE;
146 0 : *NbBits = qp->drawOrderNbBits;
147 0 : b_min->x = MAX(b_min->x, qp->drawOrderMin);
148 0 : b_max->x = MIN(b_max->x, qp->drawOrderMax);
149 0 : return GF_TRUE;
150 490 : case QC_COLOR:
151 490 : if (!qp->colorQuant) return GF_FALSE;
152 490 : *NbBits = qp->colorNbBits;
153 490 : b_min->x = b_min->y = b_min->z = MAX(b_min->x, qp->colorMin);
154 490 : b_max->x = b_max->y = b_max->z = MIN(b_max->x, qp->colorMax);
155 490 : return GF_TRUE;
156 16 : case QC_TEXTURE_COORD:
157 16 : if (!qp->textureCoordinateQuant) return GF_FALSE;
158 16 : *NbBits = qp->textureCoordinateNbBits;
159 16 : b_min->x = b_min->y = b_min->z = MAX(b_min->x, qp->textureCoordinateMin);
160 16 : b_max->x = b_max->y = b_max->z = MIN(b_max->x, qp->textureCoordinateMax);
161 16 : return GF_TRUE;
162 75 : case QC_ANGLE:
163 75 : if (!qp->angleQuant) return GF_FALSE;
164 75 : *NbBits = qp->angleNbBits;
165 75 : b_min->x = b_min->y = b_min->z = MAX(b_min->x, qp->angleMin);
166 75 : b_max->x = b_max->y = b_max->z = MIN(b_max->x, qp->angleMax);
167 75 : return GF_TRUE;
168 207 : case QC_SCALE:
169 207 : if (!qp->scaleQuant) return GF_FALSE;
170 0 : *NbBits = qp->scaleNbBits;
171 0 : b_min->x = b_min->y = b_min->z = MAX(b_min->x, qp->scaleMin);
172 0 : b_max->x = b_max->y = b_max->z = MIN(b_max->x, qp->scaleMax);
173 0 : return GF_TRUE;
174 64 : case QC_INTERPOL_KEYS:
175 64 : if (!qp->keyQuant) return GF_FALSE;
176 64 : *NbBits = qp->keyNbBits;
177 64 : b_min->x = MAX(b_min->x, qp->keyMin);
178 64 : b_min->y = MAX(b_min->y, qp->keyMin);
179 64 : b_min->z = MAX(b_min->z, qp->keyMin);
180 64 : b_max->x = MIN(b_max->x, qp->keyMax);
181 64 : b_max->y = MIN(b_max->y, qp->keyMax);
182 64 : b_max->z = MIN(b_max->z, qp->keyMax);
183 64 : return GF_TRUE;
184 105 : case QC_NORMALS:
185 105 : if (!qp->normalQuant) return GF_FALSE;
186 105 : *NbBits = qp->normalNbBits;
187 105 : b_min->x = b_min->y = b_min->z = 0;
188 105 : b_max->x = b_max->y = b_max->z = FIX_ONE;
189 105 : return GF_TRUE;
190 43 : case QC_ROTATION:
191 43 : if (!qp->normalQuant) return GF_FALSE;
192 43 : *NbBits = qp->normalNbBits;
193 43 : b_min->x = b_min->y = b_min->z = 0;
194 43 : b_max->x = b_max->y = b_max->z = FIX_ONE;
195 43 : return GF_TRUE;
196 1170 : case QC_SIZE_3D:
197 1170 : if (!qp->sizeQuant) return GF_FALSE;
198 0 : *NbBits = qp->sizeNbBits;
199 0 : b_min->x = b_min->y = b_min->z = MAX(b_min->x, qp->sizeMin);
200 0 : b_max->x = b_max->y = b_max->z = MIN(b_max->x, qp->sizeMax);
201 0 : return GF_TRUE;
202 82 : case QC_SIZE_2D:
203 82 : if (!qp->sizeQuant) return GF_FALSE;
204 0 : *NbBits = qp->sizeNbBits;
205 0 : b_min->x = b_min->y = b_min->z = MAX(b_min->x, qp->sizeMin);
206 0 : b_max->x = b_max->y = b_max->z = MIN(b_max->x, qp->sizeMax);
207 0 : 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 0 : case QC_RESERVED:
217 0 : *NbBits = 0;
218 0 : return GF_TRUE;
219 0 : default:
220 0 : return GF_FALSE;
221 : }
222 : }
223 :
224 :
225 : //Linear inverse Quantization for floats
226 0 : Fixed Q_InverseQuantize(Fixed Min, Fixed Max, u32 NbBits, u32 value)
227 : {
228 1155 : if (!value) return Min;
229 915 : if (value == (u32) ((1 << NbBits) - 1) ) return Max;
230 510 : return Min + gf_muldiv(Max - Min, INT2FIX(value), INT2FIX( (1 << NbBits) - 1) );
231 : }
232 :
233 :
234 480 : GF_Err Q_DecFloat(GF_BifsDecoder *codec, GF_BitStream *bs, u32 FieldType, SFVec3f BMin, SFVec3f BMax, u32 NbBits, void *field_ptr)
235 : {
236 480 : switch (FieldType) {
237 : case GF_SG_VRML_SFINT32:
238 : return GF_NON_COMPLIANT_BITSTREAM;
239 30 : case GF_SG_VRML_SFFLOAT:
240 60 : *((SFFloat *)field_ptr) = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits));
241 30 : return GF_OK;
242 360 : case GF_SG_VRML_SFVEC2F:
243 720 : ((SFVec2f *)field_ptr)->x = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits));
244 720 : ((SFVec2f *)field_ptr)->y = Q_InverseQuantize(BMin.y, BMax.y, NbBits, gf_bs_read_int(bs, NbBits));
245 360 : return GF_OK;
246 15 : case GF_SG_VRML_SFVEC3F:
247 30 : ((SFVec3f *)field_ptr)->x = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits));
248 30 : ((SFVec3f *)field_ptr)->y = Q_InverseQuantize(BMin.y, BMax.y, NbBits, gf_bs_read_int(bs, NbBits));
249 30 : ((SFVec3f *)field_ptr)->z = Q_InverseQuantize(BMin.z, BMax.z, NbBits, gf_bs_read_int(bs, NbBits));
250 15 : return GF_OK;
251 75 : case GF_SG_VRML_SFCOLOR:
252 150 : ((SFColor *)field_ptr)->red = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits));
253 150 : ((SFColor *)field_ptr)->green = Q_InverseQuantize(BMin.y, BMax.y, NbBits, gf_bs_read_int(bs, NbBits));
254 150 : ((SFColor *)field_ptr)->blue = Q_InverseQuantize(BMin.z, BMax.z, NbBits, gf_bs_read_int(bs, NbBits));
255 75 : return GF_OK;
256 :
257 : case GF_SG_VRML_SFROTATION:
258 : //forbidden in this Q mode
259 : return GF_NON_COMPLIANT_BITSTREAM;
260 : }
261 0 : 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
267 0 : GF_Err Q_DecInt(GF_BifsDecoder *codec, GF_BitStream *bs, u32 QType, SFInt32 b_min, u32 NbBits, void *field_ptr)
268 : {
269 45 : switch (QType) {
270 45 : case QC_LINEAR_SCALAR:
271 : case QC_COORD_INDEX:
272 45 : *((SFInt32 *)field_ptr) = gf_bs_read_int(bs, NbBits) + b_min;
273 0 : 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)
281 60 : 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 60 : if (NbComp != 2 && NbComp != 3) return GF_BAD_PARAM;
289 :
290 : //only 2 or 3 comp in the quantized version
291 : dir = 1;
292 60 : if(NbComp == 2) dir -= 2 * gf_bs_read_int(bs, 1);
293 :
294 60 : orient = gf_bs_read_int(bs, 2);
295 :
296 195 : for(i=0; i<NbComp; i++) {
297 135 : value = gf_bs_read_int(bs, NbBits) - (1 << (NbBits-1) );
298 135 : sign = (value >= 0) ? 1 : -1;
299 270 : m_ft[i] = sign * Q_InverseQuantize(0, 1, NbBits-1, sign*value);
300 : }
301 : delta = 1;
302 135 : for (i=0; i<NbComp; i++) {
303 135 : tang[i] = gf_tan(gf_mulfix(GF_PI/4, m_ft[i]) );
304 135 : delta += gf_mulfix(tang[i], tang[i]);
305 : }
306 60 : delta = gf_divfix(INT2FIX(dir), gf_sqrt(delta) );
307 60 : m_ft[orient] = delta;
308 :
309 195 : for (i=0; i<NbComp; i++) {
310 135 : m_ft[ (orient + i+1) % (NbComp+1) ] = gf_mulfix(tang[i], delta);
311 : }
312 : return GF_OK;
313 : }
314 :
315 : //parses a rotation
316 15 : 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 15 : e = Q_DecCoordOnUnitSphere(codec, bs, NbBits, 3, comp);
323 15 : if (e) return e;
324 :
325 15 : q = 2 * gf_acos(comp[0]);
326 15 : sin2 = gf_sin(q / 2);
327 :
328 15 : if (ABS(sin2) <= FIX_EPSILON) {
329 0 : for (i=1; i<4; i++) comp[i] = 0;
330 0 : comp[3] = FIX_ONE;
331 : } else {
332 45 : for (i=1; i<4; i++) comp[i] = gf_divfix(comp[i], sin2);
333 : }
334 15 : ((SFRotation *)field_ptr)->x = comp[1];
335 15 : ((SFRotation *)field_ptr)->y = comp[2];
336 15 : ((SFRotation *)field_ptr)->z = comp[3];
337 15 : ((SFRotation *)field_ptr)->q = q;
338 15 : return GF_OK;
339 : }
340 :
341 : //parses a Normal vec
342 45 : 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 45 : e = Q_DecCoordOnUnitSphere(codec, bs, NbBits, 2, comp);
348 45 : if (e) return e;
349 45 : v.x = comp[0];
350 45 : v.y = comp[1];
351 45 : v.z = comp[2];
352 45 : gf_vec_norm(&v);
353 45 : *((SFVec3f *)field_ptr) = v;
354 45 : return GF_OK;
355 : }
356 :
357 1065 : 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 1065 : if (!codec->ActiveQP) return GF_EOS;
368 : /*check FieldType*/
369 1065 : 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 645 : HasQ = gf_bifs_get_aq_info(node, field->fieldIndex, &QType, &AType, &b_min, &b_max, &NbBits);
384 645 : if (!HasQ || !QType) return GF_EOS;
385 :
386 : /*get NbBits for QP14 (QC_COORD_INDEX)*/
387 615 : if (QType == QC_COORD_INDEX) {
388 30 : 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 30 : if (!NbBits) return GF_NON_COMPLIANT_BITSTREAM;
391 : }
392 :
393 615 : BMin.x = BMin.y = BMin.z = b_min;
394 615 : BMax.x = BMax.y = BMax.z = b_max;
395 :
396 : /*check is the QP is on and retrieves the bounds*/
397 615 : if (!Q_IsTypeOn(codec->ActiveQP, QType, &NbBits, &BMin, &BMax)) return GF_EOS;
398 :
399 : /*ok the field is Quantized, dequantize*/
400 585 : switch (QType) {
401 : //these are all SFFloat quantized on n fields
402 480 : 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 480 : e = Q_DecFloat(codec, bs, field->fieldType, BMin, BMax, NbBits, field->far_ptr);
413 480 : break;
414 : //SFInt types
415 45 : case QC_LINEAR_SCALAR:
416 : case QC_COORD_INDEX:
417 45 : e = Q_DecInt(codec, bs, QType, (SFInt32) b_min, NbBits, field->far_ptr);
418 : break;
419 : //normalized fields (normals and vectors)
420 45 : case QC_NORMALS:
421 : //normal quant is only for SFVec3F
422 45 : if (field->fieldType != GF_SG_VRML_SFVEC3F) return GF_NON_COMPLIANT_BITSTREAM;
423 45 : e = Q_DecNormal(codec, bs, NbBits, field->far_ptr);
424 45 : break;
425 15 : case QC_ROTATION:
426 : //normal quant is only for SFRotation
427 15 : if (field->fieldType != GF_SG_VRML_SFROTATION) return GF_NON_COMPLIANT_BITSTREAM;
428 15 : e = Q_DecRotation(codec, bs, NbBits, field->far_ptr);
429 15 : break;
430 : default:
431 : return GF_BAD_PARAM;
432 : }
433 :
434 540 : if (e) return e;
435 : return GF_OK;
436 : }
437 :
438 : #endif /*GPAC_DISABLE_BIFS*/
|