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*/
|