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 / MPEG-4 ObjectDescriptor 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 <gpac/internal/odf_dev.h>
27 #include <gpac/utf.h>
28 
29 #define DATE_CODING_BIT_LEN	40
30 
31 #ifndef GPAC_MINIMAL_ODF
32 
OD_ReadUTF8String(GF_BitStream * bs,char ** string,Bool isUTF8,u32 * read)33 static GFINLINE GF_Err OD_ReadUTF8String(GF_BitStream *bs, char **string, Bool isUTF8, u32 *read)
34 {
35 	u32 len;
36 	*read = 1;
37 	len = gf_bs_read_int(bs, 8) + 1;
38 	if (!isUTF8) len *= 2;
39 	(*string) = (char *)gf_malloc(sizeof(char)*len);
40 	if (!(*string)) return GF_OUT_OF_MEM;
41 	gf_bs_read_data(bs, (*string), len);
42 	*read += len;
43 	return GF_OK;
44 }
45 
OD_SizeUTF8String(char * string,Bool isUTF8)46 static GFINLINE u32 OD_SizeUTF8String(char *string, Bool isUTF8)
47 {
48 	if (isUTF8) return 1 + (u32)strlen(string);
49 	return 1 + 2 * (u32)gf_utf8_wcslen((const unsigned short *)string);
50 }
51 
OD_WriteUTF8String(GF_BitStream * bs,char * string,Bool isUTF8)52 static GFINLINE void OD_WriteUTF8String(GF_BitStream *bs, char *string, Bool isUTF8)
53 {
54 	u32 len;
55 	if (isUTF8) {
56 		len = (u32)strlen(string);
57 		gf_bs_write_int(bs, len, 8);
58 		gf_bs_write_data(bs, string, len);
59 	}
60 	else {
61 		len = (u32)gf_utf8_wcslen((const unsigned short *)string);
62 		gf_bs_write_int(bs, len, 8);
63 		gf_bs_write_data(bs, string, len * 2);
64 	}
65 }
66 
67 #endif // GPAC_MINIMAL_ODF
68 
69 /*use to parse strings read the length as well - Warning : the alloc is done here !!*/
gf_odf_read_url_string(GF_BitStream * bs,char ** string,u32 * readBytes)70 GF_Err gf_odf_read_url_string(GF_BitStream *bs, char **string, u32 *readBytes)
71 {
72 	u32 length;
73 	*readBytes = 0;
74 
75 	/*if the string is not NULL, return an error...*/
76 	if (*string != NULL) return GF_BAD_PARAM;
77 
78 	/*the len is always on 8 bits*/
79 	length = gf_bs_read_int(bs, 8);
80 	*readBytes = 1;
81 	/*JLF AMD to MPEG-4 systems :) - This is not conformant at all, just hoping MPEG will accept it soon
82 	since 255bytes URL is a real pain in the neck*/
83 	if (!length) {
84 		length = gf_bs_read_int(bs, 32);
85 		*readBytes += 4;
86 	}
87 
88 	/*we want to use strlen to get rid of "stringLength" => we need an extra 0*/
89 	(*string) = (char *)gf_malloc(length + 1);
90 	if (!string) return GF_OUT_OF_MEM;
91 	gf_bs_read_data(bs, (*string), length);
92 	*readBytes += length;
93 	(*string)[length] = 0;
94 	return GF_OK;
95 }
96 
97 /*writes string*/
gf_odf_write_url_string(GF_BitStream * bs,char * string)98 GF_Err gf_odf_write_url_string(GF_BitStream *bs, char *string)
99 {
100 	u32 len;
101 	/*we accept NULL strings now*/
102 	if (!string) {
103 		gf_bs_write_int(bs, 0, 8);
104 		return GF_OK;
105 	}
106 	len = (u32)strlen(string);
107 	if (len > 255) {
108 		gf_bs_write_int(bs, 0, 8);
109 		gf_bs_write_int(bs, len, 32);
110 	}
111 	else {
112 		gf_bs_write_int(bs, len, 8);
113 	}
114 	gf_bs_write_data(bs, string, len);
115 	return GF_OK;
116 }
117 
gf_odf_size_url_string(char * string)118 u32 gf_odf_size_url_string(char *string)
119 {
120 	u32 len = (u32)strlen(string);
121 	if (len>255) return len + 5;
122 	return len + 1;
123 }
124 
gf_odf_new_esd()125 GF_Descriptor *gf_odf_new_esd()
126 {
127 	GF_ESD *newDesc = (GF_ESD *)gf_malloc(sizeof(GF_ESD));
128 	if (!newDesc) return NULL;
129 	memset(newDesc, 0, sizeof(GF_ESD));
130 	newDesc->IPIDataSet = gf_list_new();
131 	newDesc->IPMPDescriptorPointers = gf_list_new();
132 	newDesc->extensionDescriptors = gf_list_new();
133 	newDesc->tag = GF_ODF_ESD_TAG;
134 	return (GF_Descriptor *)newDesc;
135 }
136 
137 
gf_odf_del_esd(GF_ESD * esd)138 GF_Err gf_odf_del_esd(GF_ESD *esd)
139 {
140 	GF_Err e;
141 	if (!esd) return GF_BAD_PARAM;
142 	if (esd->URLString)	gf_free(esd->URLString);
143 
144 	if (esd->decoderConfig) {
145 		e = gf_odf_delete_descriptor((GF_Descriptor *)esd->decoderConfig);
146 		if (e) return e;
147 	}
148 	if (esd->slConfig) {
149 		e = gf_odf_delete_descriptor((GF_Descriptor *)esd->slConfig);
150 		if (e) return e;
151 	}
152 	if (esd->ipiPtr) {
153 		e = gf_odf_delete_descriptor((GF_Descriptor *)esd->ipiPtr);
154 		if (e) return e;
155 	}
156 	if (esd->qos) {
157 		e = gf_odf_delete_descriptor((GF_Descriptor *)esd->qos);
158 		if (e) return e;
159 	}
160 	if (esd->RegDescriptor) {
161 		e = gf_odf_delete_descriptor((GF_Descriptor *)esd->RegDescriptor);
162 		if (e) return e;
163 	}
164 	if (esd->langDesc) {
165 		e = gf_odf_delete_descriptor((GF_Descriptor *)esd->langDesc);
166 		if (e) return e;
167 	}
168 
169 	e = gf_odf_delete_descriptor_list(esd->IPIDataSet);
170 	if (e) return e;
171 	e = gf_odf_delete_descriptor_list(esd->IPMPDescriptorPointers);
172 	if (e) return e;
173 	e = gf_odf_delete_descriptor_list(esd->extensionDescriptors);
174 	if (e) return e;
175 	gf_free(esd);
176 	return GF_OK;
177 }
178 
179 
AddDescriptorToESD(GF_ESD * esd,GF_Descriptor * desc)180 GF_Err AddDescriptorToESD(GF_ESD *esd, GF_Descriptor *desc)
181 {
182 	if (!esd || !desc) return GF_BAD_PARAM;
183 
184 	switch (desc->tag) {
185 	case GF_ODF_DCD_TAG:
186 		if (esd->decoderConfig) return GF_ODF_INVALID_DESCRIPTOR;
187 		esd->decoderConfig = (GF_DecoderConfig *)desc;
188 		break;
189 
190 	case GF_ODF_SLC_TAG:
191 		if (esd->slConfig) return GF_ODF_INVALID_DESCRIPTOR;
192 		esd->slConfig = (GF_SLConfig *)desc;
193 		break;
194 
195 	case GF_ODF_MUXINFO_TAG:
196 		gf_list_add(esd->extensionDescriptors, desc);
197 		break;
198 
199 	case GF_ODF_LANG_TAG:
200 		if (esd->langDesc) return GF_ODF_INVALID_DESCRIPTOR;
201 		esd->langDesc = (GF_Language *)desc;
202 		break;
203 
204 #ifndef GPAC_MINIMAL_ODF
205 		//the GF_ODF_ISOM_IPI_PTR_TAG is only used in the file format and replaces GF_ODF_IPI_PTR_TAG...
206 	case GF_ODF_ISOM_IPI_PTR_TAG:
207 	case GF_ODF_IPI_PTR_TAG:
208 		if (esd->ipiPtr) return GF_ODF_INVALID_DESCRIPTOR;
209 		esd->ipiPtr = (GF_IPIPtr *)desc;
210 		break;
211 
212 	case GF_ODF_QOS_TAG:
213 		if (esd->qos) return GF_ODF_INVALID_DESCRIPTOR;
214 		esd->qos = (GF_QoS_Descriptor *)desc;
215 		break;
216 
217 	case GF_ODF_CI_TAG:
218 	case GF_ODF_SCI_TAG:
219 		return gf_list_add(esd->IPIDataSet, desc);
220 
221 		//we use the same struct for v1 and v2 IPMP DPs
222 	case GF_ODF_IPMP_PTR_TAG:
223 		return gf_list_add(esd->IPMPDescriptorPointers, desc);
224 
225 	case GF_ODF_REG_TAG:
226 		if (esd->RegDescriptor) return GF_ODF_INVALID_DESCRIPTOR;
227 		esd->RegDescriptor = (GF_Registration *)desc;
228 		break;
229 #endif
230 
231 	default:
232 		if ((desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
233 			(desc->tag <= GF_ODF_EXT_END_TAG)) {
234 			return gf_list_add(esd->extensionDescriptors, desc);
235 		}
236 		gf_odf_delete_descriptor(desc);
237 		return GF_OK;
238 	}
239 
240 	return GF_OK;
241 }
242 
gf_odf_read_esd(GF_BitStream * bs,GF_ESD * esd,u32 DescSize)243 GF_Err gf_odf_read_esd(GF_BitStream *bs, GF_ESD *esd, u32 DescSize)
244 {
245 	GF_Err e = GF_OK;
246 	u32 ocrflag, urlflag, streamdependflag, tmp_size, nbBytes, read;
247 
248 	if (!esd) return GF_BAD_PARAM;
249 
250 	nbBytes = 0;
251 
252 	esd->ESID = gf_bs_read_int(bs, 16);
253 	streamdependflag = gf_bs_read_int(bs, 1);
254 	urlflag = gf_bs_read_int(bs, 1);
255 	ocrflag = gf_bs_read_int(bs, 1);
256 	esd->streamPriority = gf_bs_read_int(bs, 5);
257 	nbBytes += 3;
258 
259 	if (streamdependflag) {
260 		esd->dependsOnESID = gf_bs_read_int(bs, 16);
261 		nbBytes += 2;
262 	}
263 
264 	if (urlflag) {
265 		e = gf_odf_read_url_string(bs, &esd->URLString, &read);
266 		if (e) return e;
267 		nbBytes += read;
268 	}
269 	if (ocrflag) {
270 		esd->OCRESID = gf_bs_read_int(bs, 16);
271 		nbBytes += 2;
272 	}
273 	/*fix broken sync*/
274 	//	if (esd->OCRESID == esd->ESID) esd->OCRESID = 0;
275 
276 	while (nbBytes < DescSize) {
277 		GF_Descriptor *tmp = NULL;
278 		e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
279 		/*fix for iPod files*/
280 		if (e == GF_ODF_INVALID_DESCRIPTOR) {
281 			nbBytes += tmp_size;
282 			if (nbBytes>DescSize) return e;
283 			gf_bs_read_int(bs, DescSize - nbBytes);
284 			return GF_OK;
285 		}
286 		if (e) return e;
287 		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
288 		e = AddDescriptorToESD(esd, tmp);
289 		if (e) return e;
290 		nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
291 
292 		//apple fix
293 		if (!tmp_size) nbBytes = DescSize;
294 
295 	}
296 	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
297 	return e;
298 
299 }
300 
gf_odf_size_esd(GF_ESD * esd,u32 * outSize)301 GF_Err gf_odf_size_esd(GF_ESD *esd, u32 *outSize)
302 {
303 	GF_Err e;
304 	u32 tmpSize;
305 	if (!esd) return GF_BAD_PARAM;
306 
307 	*outSize = 0;
308 	*outSize += 3;
309 
310 	/*this helps keeping proper sync: some people argue that OCR_ES_ID == ES_ID is a circular reference
311 	of streams. Since this is equivalent to no OCR_ES_ID, keep it that way*/
312 	//	if (esd->OCRESID == esd->ESID) esd->OCRESID = 0;
313 
314 	if (esd->dependsOnESID) *outSize += 2;
315 	if (esd->URLString) *outSize += gf_odf_size_url_string(esd->URLString);
316 	if (esd->OCRESID) *outSize += 2;
317 
318 	if (esd->decoderConfig) {
319 		e = gf_odf_size_descriptor((GF_Descriptor *)esd->decoderConfig, &tmpSize);
320 		if (e) return e;
321 		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
322 	}
323 	if (esd->slConfig) {
324 		e = gf_odf_size_descriptor((GF_Descriptor *)esd->slConfig, &tmpSize);
325 		if (e) return e;
326 		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
327 	}
328 	if (esd->ipiPtr) {
329 		e = gf_odf_size_descriptor((GF_Descriptor *)esd->ipiPtr, &tmpSize);
330 		if (e) return e;
331 		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
332 	}
333 	if (esd->langDesc) {
334 		e = gf_odf_size_descriptor((GF_Descriptor *)esd->langDesc, &tmpSize);
335 		if (e) return e;
336 		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
337 	}
338 
339 	e = gf_odf_size_descriptor_list(esd->IPIDataSet, outSize);
340 	if (e) return e;
341 	e = gf_odf_size_descriptor_list(esd->IPMPDescriptorPointers, outSize);
342 	if (e) return e;
343 	if (esd->qos) {
344 		e = gf_odf_size_descriptor((GF_Descriptor *)esd->qos, &tmpSize);
345 		if (e) return e;
346 		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
347 	}
348 	if (esd->RegDescriptor) {
349 		e = gf_odf_size_descriptor((GF_Descriptor *)esd->RegDescriptor, &tmpSize);
350 		if (e) return e;
351 		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
352 	}
353 	return gf_odf_size_descriptor_list(esd->extensionDescriptors, outSize);
354 }
355 
gf_odf_write_esd(GF_BitStream * bs,GF_ESD * esd)356 GF_Err gf_odf_write_esd(GF_BitStream *bs, GF_ESD *esd)
357 {
358 	GF_Err e;
359 	u32 size;
360 	if (!esd) return GF_BAD_PARAM;
361 
362 	e = gf_odf_size_descriptor((GF_Descriptor *)esd, &size);
363 	if (e) return e;
364 	e = gf_odf_write_base_descriptor(bs, esd->tag, size);
365 	if (e) return e;
366 
367 	gf_bs_write_int(bs, esd->ESID, 16);
368 	gf_bs_write_int(bs, esd->dependsOnESID ? 1 : 0, 1);
369 	gf_bs_write_int(bs, esd->URLString != NULL ? 1 : 0, 1);
370 	gf_bs_write_int(bs, esd->OCRESID ? 1 : 0, 1);
371 	gf_bs_write_int(bs, esd->streamPriority, 5);
372 
373 	if (esd->dependsOnESID) {
374 		gf_bs_write_int(bs, esd->dependsOnESID, 16);
375 	}
376 	if (esd->URLString) {
377 		e = gf_odf_write_url_string(bs, esd->URLString);
378 		if (e) return e;
379 	}
380 
381 
382 	if (esd->OCRESID) {
383 		gf_bs_write_int(bs, esd->OCRESID, 16);
384 	}
385 	if (esd->decoderConfig) {
386 		e = gf_odf_write_descriptor(bs, (GF_Descriptor *)esd->decoderConfig);
387 		if (e) return e;
388 	}
389 	if (esd->slConfig) {
390 		e = gf_odf_write_descriptor(bs, (GF_Descriptor *)esd->slConfig);
391 		if (e) return e;
392 	}
393 	if (esd->ipiPtr) {
394 		e = gf_odf_write_descriptor(bs, (GF_Descriptor *)esd->ipiPtr);
395 		if (e) return e;
396 	}
397 	if (esd->langDesc) {
398 		e = gf_odf_write_descriptor(bs, (GF_Descriptor *)esd->langDesc);
399 		if (e) return e;
400 	}
401 
402 	e = gf_odf_write_descriptor_list(bs, esd->IPIDataSet);
403 	if (e) return e;
404 	e = gf_odf_write_descriptor_list(bs, esd->IPMPDescriptorPointers);
405 	if (e) return e;
406 	if (esd->qos) {
407 		e = gf_odf_write_descriptor(bs, (GF_Descriptor *)esd->qos);
408 		if (e) return e;
409 	}
410 	if (esd->RegDescriptor) {
411 		e = gf_odf_write_descriptor(bs, (GF_Descriptor *)esd->RegDescriptor);
412 		if (e) return e;
413 	}
414 	return gf_odf_write_descriptor_list(bs, esd->extensionDescriptors);
415 }
416 
gf_odf_new_iod()417 GF_Descriptor *gf_odf_new_iod()
418 {
419 	GF_InitialObjectDescriptor *newDesc = (GF_InitialObjectDescriptor *)gf_malloc(sizeof(GF_InitialObjectDescriptor));
420 	if (!newDesc) return NULL;
421 	memset(newDesc, 0, sizeof(GF_InitialObjectDescriptor));
422 
423 	newDesc->ESDescriptors = gf_list_new();
424 	newDesc->OCIDescriptors = gf_list_new();
425 	newDesc->IPMP_Descriptors = gf_list_new();
426 
427 	newDesc->extensionDescriptors = gf_list_new();
428 	newDesc->tag = GF_ODF_IOD_TAG;
429 	return (GF_Descriptor *)newDesc;
430 }
431 
gf_odf_del_iod(GF_InitialObjectDescriptor * iod)432 GF_Err gf_odf_del_iod(GF_InitialObjectDescriptor *iod)
433 {
434 	GF_Err e;
435 	if (!iod) return GF_BAD_PARAM;
436 	if (iod->URLString)	gf_free(iod->URLString);
437 	e = gf_odf_delete_descriptor_list(iod->ESDescriptors);
438 	if (e) return e;
439 	e = gf_odf_delete_descriptor_list(iod->OCIDescriptors);
440 	if (e) return e;
441 	e = gf_odf_delete_descriptor_list(iod->IPMP_Descriptors);
442 	if (e) return e;
443 	e = gf_odf_delete_descriptor_list(iod->extensionDescriptors);
444 	if (e) return e;
445 	if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *)iod->IPMPToolList);
446 	gf_free(iod);
447 	return GF_OK;
448 }
449 
AddDescriptorToIOD(GF_InitialObjectDescriptor * iod,GF_Descriptor * desc)450 GF_Err AddDescriptorToIOD(GF_InitialObjectDescriptor *iod, GF_Descriptor *desc)
451 {
452 	if (!iod || !desc) return GF_BAD_PARAM;
453 
454 	switch (desc->tag) {
455 	case GF_ODF_ESD_TAG:
456 		return gf_list_add(iod->ESDescriptors, desc);
457 
458 		//we use the same struct for v1 and v2 IPMP DPs
459 	case GF_ODF_IPMP_PTR_TAG:
460 		/*IPMPX*/
461 	case GF_ODF_IPMP_TAG:
462 		return gf_list_add(iod->IPMP_Descriptors, desc);
463 
464 		/*IPMPX*/
465 	case GF_ODF_IPMP_TL_TAG:
466 		if (iod->IPMPToolList) gf_odf_desc_del((GF_Descriptor *)iod->IPMPToolList);
467 		iod->IPMPToolList = (GF_IPMP_ToolList *)desc;
468 		return GF_OK;
469 
470 	default:
471 		break;
472 	}
473 	if ((desc->tag >= GF_ODF_OCI_BEGIN_TAG) && (desc->tag <= GF_ODF_OCI_END_TAG)) return gf_list_add(iod->OCIDescriptors, desc);
474 	if ((desc->tag >= GF_ODF_EXT_BEGIN_TAG) && (desc->tag <= GF_ODF_EXT_END_TAG)) return gf_list_add(iod->extensionDescriptors, desc);
475 	return GF_BAD_PARAM;
476 }
477 
gf_odf_read_iod(GF_BitStream * bs,GF_InitialObjectDescriptor * iod,u32 DescSize)478 GF_Err gf_odf_read_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod, u32 DescSize)
479 {
480 	GF_Err e;
481 	u32 urlflag, read;
482 	u32 tmp_size, nbBytes = 0;
483 	if (!iod) return GF_BAD_PARAM;
484 
485 	iod->objectDescriptorID = gf_bs_read_int(bs, 10);
486 	urlflag = gf_bs_read_int(bs, 1);
487 	iod->inlineProfileFlag = gf_bs_read_int(bs, 1);
488 	/*reserved = */gf_bs_read_int(bs, 4);
489 	nbBytes += 2;
490 
491 	if (urlflag) {
492 		e = gf_odf_read_url_string(bs, &iod->URLString, &read);
493 		if (e) return e;
494 		nbBytes += read;
495 	}
496 	else {
497 		iod->OD_profileAndLevel = gf_bs_read_int(bs, 8);
498 		iod->scene_profileAndLevel = gf_bs_read_int(bs, 8);
499 		iod->audio_profileAndLevel = gf_bs_read_int(bs, 8);
500 		iod->visual_profileAndLevel = gf_bs_read_int(bs, 8);
501 		iod->graphics_profileAndLevel = gf_bs_read_int(bs, 8);
502 		nbBytes += 5;
503 	}
504 
505 	while (nbBytes < DescSize) {
506 		GF_Descriptor *tmp = NULL;
507 		e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
508 		if (e) return e;
509 		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
510 		e = AddDescriptorToIOD(iod, tmp);
511 		if (e) return e;
512 		nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
513 	}
514 	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
515 	return GF_OK;
516 }
517 
gf_odf_size_iod(GF_InitialObjectDescriptor * iod,u32 * outSize)518 GF_Err gf_odf_size_iod(GF_InitialObjectDescriptor *iod, u32 *outSize)
519 {
520 	GF_Err e;
521 	if (!iod) return GF_BAD_PARAM;
522 
523 	*outSize = 0;
524 	*outSize += 2;
525 	if (iod->URLString) {
526 		*outSize += gf_odf_size_url_string(iod->URLString);
527 	}
528 	else {
529 		*outSize += 5;
530 		e = gf_odf_size_descriptor_list(iod->ESDescriptors, outSize);
531 		if (e) return e;
532 		e = gf_odf_size_descriptor_list(iod->OCIDescriptors, outSize);
533 		if (e) return e;
534 		e = gf_odf_size_descriptor_list(iod->IPMP_Descriptors, outSize);
535 		if (e) return e;
536 
537 	}
538 	e = gf_odf_size_descriptor_list(iod->extensionDescriptors, outSize);
539 	if (e) return e;
540 	if (iod->IPMPToolList) {
541 		u32 tmpSize;
542 		e = gf_odf_size_descriptor((GF_Descriptor *)iod->IPMPToolList, &tmpSize);
543 		if (e) return e;
544 		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
545 	}
546 	return GF_OK;
547 }
548 
gf_odf_write_iod(GF_BitStream * bs,GF_InitialObjectDescriptor * iod)549 GF_Err gf_odf_write_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod)
550 {
551 	GF_Err e;
552 	u32 size;
553 	if (!iod) return GF_BAD_PARAM;
554 
555 	e = gf_odf_size_descriptor((GF_Descriptor *)iod, &size);
556 	if (e) return e;
557 	e = gf_odf_write_base_descriptor(bs, iod->tag, size);
558 	if (e) return e;
559 
560 	gf_bs_write_int(bs, iod->objectDescriptorID, 10);
561 	gf_bs_write_int(bs, iod->URLString != NULL ? 1 : 0, 1);
562 	gf_bs_write_int(bs, iod->inlineProfileFlag, 1);
563 	gf_bs_write_int(bs, 15, 4);		//reserved: 0b1111 == 15
564 
565 	if (iod->URLString) {
566 		gf_odf_write_url_string(bs, iod->URLString);
567 	}
568 	else {
569 		gf_bs_write_int(bs, iod->OD_profileAndLevel, 8);
570 		gf_bs_write_int(bs, iod->scene_profileAndLevel, 8);
571 		gf_bs_write_int(bs, iod->audio_profileAndLevel, 8);
572 		gf_bs_write_int(bs, iod->visual_profileAndLevel, 8);
573 		gf_bs_write_int(bs, iod->graphics_profileAndLevel, 8);
574 		e = gf_odf_write_descriptor_list(bs, iod->ESDescriptors);
575 		if (e) return e;
576 		e = gf_odf_write_descriptor_list(bs, iod->OCIDescriptors);
577 		if (e) return e;
578 		e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
579 		if (e) return e;
580 		e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_TAG);
581 		if (e) return e;
582 		if (iod->IPMPToolList) {
583 			e = gf_odf_write_descriptor(bs, (GF_Descriptor *)iod->IPMPToolList);
584 			if (e) return e;
585 		}
586 	}
587 	return gf_odf_write_descriptor_list(bs, iod->extensionDescriptors);
588 }
589 
590 
591 
gf_odf_new_od()592 GF_Descriptor *gf_odf_new_od()
593 {
594 	GF_ObjectDescriptor *newDesc;
595 	GF_SAFEALLOC(newDesc, GF_ObjectDescriptor);
596 	if (!newDesc) return NULL;
597 
598 	newDesc->URLString = NULL;
599 	newDesc->ESDescriptors = gf_list_new();
600 	newDesc->OCIDescriptors = gf_list_new();
601 	newDesc->IPMP_Descriptors = gf_list_new();
602 	newDesc->extensionDescriptors = gf_list_new();
603 	newDesc->objectDescriptorID = 0;
604 	newDesc->tag = GF_ODF_OD_TAG;
605 	return (GF_Descriptor *)newDesc;
606 }
607 
gf_odf_del_od(GF_ObjectDescriptor * od)608 GF_Err gf_odf_del_od(GF_ObjectDescriptor *od)
609 {
610 	GF_Err e;
611 	if (!od) return GF_BAD_PARAM;
612 	if (od->URLString)	gf_free(od->URLString);
613 	e = gf_odf_delete_descriptor_list(od->ESDescriptors);
614 	if (e) return e;
615 	e = gf_odf_delete_descriptor_list(od->OCIDescriptors);
616 	if (e) return e;
617 	e = gf_odf_delete_descriptor_list(od->IPMP_Descriptors);
618 	if (e) return e;
619 	e = gf_odf_delete_descriptor_list(od->extensionDescriptors);
620 	if (e) return e;
621 	gf_free(od);
622 	return GF_OK;
623 }
624 
AddDescriptorToOD(GF_ObjectDescriptor * od,GF_Descriptor * desc)625 GF_Err AddDescriptorToOD(GF_ObjectDescriptor *od, GF_Descriptor *desc)
626 {
627 	if (!od || !desc) return GF_BAD_PARAM;
628 
629 	//check if we can handle ContentClassif tags
630 	if ((desc->tag >= GF_ODF_OCI_BEGIN_TAG) &&
631 		(desc->tag <= GF_ODF_OCI_END_TAG)) {
632 		return gf_list_add(od->OCIDescriptors, desc);
633 	}
634 
635 	//or extensions
636 	if ((desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
637 		(desc->tag <= GF_ODF_EXT_END_TAG)) {
638 		return gf_list_add(od->extensionDescriptors, desc);
639 	}
640 
641 	//to cope with envivio
642 	switch (desc->tag) {
643 	case GF_ODF_ESD_TAG:
644 	case GF_ODF_ESD_REF_TAG:
645 		return gf_list_add(od->ESDescriptors, desc);
646 
647 		//we use the same struct for v1 and v2 IPMP DPs
648 	case GF_ODF_IPMP_PTR_TAG:
649 	case GF_ODF_IPMP_TAG:
650 		return gf_list_add(od->IPMP_Descriptors, desc);
651 
652 	default:
653 		return GF_BAD_PARAM;
654 	}
655 }
656 
gf_odf_read_od(GF_BitStream * bs,GF_ObjectDescriptor * od,u32 DescSize)657 GF_Err gf_odf_read_od(GF_BitStream *bs, GF_ObjectDescriptor *od, u32 DescSize)
658 {
659 	GF_Err e;
660 	u32 urlflag;
661 	u32 tmpSize, nbBytes = 0;
662 	if (!od) return GF_BAD_PARAM;
663 
664 	od->objectDescriptorID = gf_bs_read_int(bs, 10);
665 	urlflag = gf_bs_read_int(bs, 1);
666 	/*reserved = */gf_bs_read_int(bs, 5);
667 	nbBytes += 2;
668 
669 	if (urlflag) {
670 		u32 read;
671 		e = gf_odf_read_url_string(bs, &od->URLString, &read);
672 		if (e) return e;
673 		nbBytes += read;
674 	}
675 
676 	while (nbBytes < DescSize) {
677 		GF_Descriptor *tmp = NULL;
678 		e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
679 		if (e) return e;
680 		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
681 		e = AddDescriptorToOD(od, tmp);
682 		if (e) return e;
683 		nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
684 	}
685 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
686 	return GF_OK;
687 }
688 
gf_odf_size_od(GF_ObjectDescriptor * od,u32 * outSize)689 GF_Err gf_odf_size_od(GF_ObjectDescriptor *od, u32 *outSize)
690 {
691 	GF_Err e;
692 	if (!od) return GF_BAD_PARAM;
693 
694 	*outSize = 2;
695 	if (od->URLString) {
696 		*outSize += gf_odf_size_url_string(od->URLString);
697 	}
698 	else {
699 		e = gf_odf_size_descriptor_list(od->ESDescriptors, outSize);
700 		if (e) return e;
701 		e = gf_odf_size_descriptor_list(od->OCIDescriptors, outSize);
702 		if (e) return e;
703 		e = gf_odf_size_descriptor_list(od->IPMP_Descriptors, outSize);
704 		if (e) return e;
705 	}
706 	return gf_odf_size_descriptor_list(od->extensionDescriptors, outSize);
707 }
708 
gf_odf_write_od(GF_BitStream * bs,GF_ObjectDescriptor * od)709 GF_Err gf_odf_write_od(GF_BitStream *bs, GF_ObjectDescriptor *od)
710 {
711 	GF_Err e;
712 	u32 size;
713 	if (!od) return GF_BAD_PARAM;
714 
715 	e = gf_odf_size_descriptor((GF_Descriptor *)od, &size);
716 	if (e) return e;
717 	e = gf_odf_write_base_descriptor(bs, od->tag, size);
718 	if (e) return e;
719 
720 	gf_bs_write_int(bs, od->objectDescriptorID, 10);
721 	gf_bs_write_int(bs, od->URLString != NULL ? 1 : 0, 1);
722 	gf_bs_write_int(bs, 31, 5);		//reserved: 0b1111.1 == 31
723 
724 	if (od->URLString) {
725 		gf_odf_write_url_string(bs, od->URLString);
726 	}
727 	else {
728 		e = gf_odf_write_descriptor_list(bs, od->ESDescriptors);
729 		if (e) return e;
730 		e = gf_odf_write_descriptor_list(bs, od->OCIDescriptors);
731 		if (e) return e;
732 		e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
733 		if (e) return e;
734 		e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_TAG);
735 		if (e) return e;
736 	}
737 	return gf_odf_write_descriptor_list(bs, od->extensionDescriptors);
738 }
739 
gf_odf_new_isom_iod()740 GF_Descriptor *gf_odf_new_isom_iod()
741 {
742 	GF_IsomInitialObjectDescriptor *newDesc = (GF_IsomInitialObjectDescriptor *)gf_malloc(sizeof(GF_IsomInitialObjectDescriptor));
743 	if (!newDesc) return NULL;
744 	memset(newDesc, 0, sizeof(GF_IsomInitialObjectDescriptor));
745 
746 	newDesc->ES_ID_IncDescriptors = gf_list_new();
747 	newDesc->ES_ID_RefDescriptors = gf_list_new();
748 	newDesc->OCIDescriptors = gf_list_new();
749 	newDesc->IPMP_Descriptors = gf_list_new();
750 	newDesc->extensionDescriptors = gf_list_new();
751 	newDesc->tag = GF_ODF_ISOM_IOD_TAG;
752 
753 	//by default create an IOD with no inline and no capabilities
754 	newDesc->audio_profileAndLevel = 0xFF;
755 	newDesc->graphics_profileAndLevel = 0xFF;
756 	newDesc->scene_profileAndLevel = 0xFF;
757 	newDesc->OD_profileAndLevel = 0xFF;
758 	newDesc->visual_profileAndLevel = 0xFF;
759 	return (GF_Descriptor *)newDesc;
760 }
761 
gf_odf_del_isom_iod(GF_IsomInitialObjectDescriptor * iod)762 GF_Err gf_odf_del_isom_iod(GF_IsomInitialObjectDescriptor *iod)
763 {
764 	GF_Err e;
765 	if (!iod) return GF_BAD_PARAM;
766 	if (iod->URLString)	gf_free(iod->URLString);
767 	e = gf_odf_delete_descriptor_list(iod->ES_ID_IncDescriptors);
768 	if (e) return e;
769 	e = gf_odf_delete_descriptor_list(iod->ES_ID_RefDescriptors);
770 	if (e) return e;
771 	e = gf_odf_delete_descriptor_list(iod->OCIDescriptors);
772 	if (e) return e;
773 	e = gf_odf_delete_descriptor_list(iod->IPMP_Descriptors);
774 	if (e) return e;
775 	e = gf_odf_delete_descriptor_list(iod->extensionDescriptors);
776 	if (e) return e;
777 	if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *)iod->IPMPToolList);
778 	gf_free(iod);
779 	return GF_OK;
780 }
781 
AddDescriptorToIsomIOD(GF_IsomInitialObjectDescriptor * iod,GF_Descriptor * desc)782 GF_Err AddDescriptorToIsomIOD(GF_IsomInitialObjectDescriptor *iod, GF_Descriptor *desc)
783 {
784 	if (!iod || !desc) return GF_BAD_PARAM;
785 
786 	switch (desc->tag) {
787 	case GF_ODF_ESD_TAG:
788 		return GF_ODF_FORBIDDEN_DESCRIPTOR;
789 
790 	case GF_ODF_ESD_INC_TAG:
791 		//there shouldn't be ref if inc
792 		if (gf_list_count(iod->ES_ID_RefDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
793 		return gf_list_add(iod->ES_ID_IncDescriptors, desc);
794 
795 	case GF_ODF_ESD_REF_TAG:
796 		//there shouldn't be inc if ref
797 		if (gf_list_count(iod->ES_ID_IncDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
798 		return gf_list_add(iod->ES_ID_RefDescriptors, desc);
799 
800 		//we use the same struct for v1 and v2 IPMP DPs
801 	case GF_ODF_IPMP_PTR_TAG:
802 	case GF_ODF_IPMP_TAG:
803 		return gf_list_add(iod->IPMP_Descriptors, desc);
804 
805 		/*IPMPX*/
806 	case GF_ODF_IPMP_TL_TAG:
807 		if (iod->IPMPToolList) gf_odf_desc_del((GF_Descriptor *)iod->IPMPToolList);
808 		iod->IPMPToolList = (GF_IPMP_ToolList *)desc;
809 		return GF_OK;
810 
811 	default:
812 		break;
813 	}
814 	//check if we can handle ContentClassif tags
815 	if ((desc->tag >= GF_ODF_OCI_BEGIN_TAG) && (desc->tag <= GF_ODF_OCI_END_TAG)) return gf_list_add(iod->OCIDescriptors, desc);
816 	//or extensions
817 	if ((desc->tag >= GF_ODF_EXT_BEGIN_TAG) && (desc->tag <= GF_ODF_EXT_END_TAG)) return gf_list_add(iod->extensionDescriptors, desc);
818 	return GF_BAD_PARAM;
819 }
820 
gf_odf_read_isom_iod(GF_BitStream * bs,GF_IsomInitialObjectDescriptor * iod,u32 DescSize)821 GF_Err gf_odf_read_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *iod, u32 DescSize)
822 {
823 	u32 nbBytes = 0, tmpSize;
824 	u32 urlflag;
825 	GF_Err e;
826 	if (!iod) return GF_BAD_PARAM;
827 
828 	iod->objectDescriptorID = gf_bs_read_int(bs, 10);
829 	urlflag = gf_bs_read_int(bs, 1);
830 	iod->inlineProfileFlag = gf_bs_read_int(bs, 1);
831 	/*reserved = */gf_bs_read_int(bs, 4);
832 	nbBytes += 2;
833 
834 	if (urlflag) {
835 		u32 read;
836 		e = gf_odf_read_url_string(bs, &iod->URLString, &read);
837 		if (e) return e;
838 		nbBytes += read;
839 	}
840 	else {
841 		iod->OD_profileAndLevel = gf_bs_read_int(bs, 8);
842 		iod->scene_profileAndLevel = gf_bs_read_int(bs, 8);
843 		iod->audio_profileAndLevel = gf_bs_read_int(bs, 8);
844 		iod->visual_profileAndLevel = gf_bs_read_int(bs, 8);
845 		iod->graphics_profileAndLevel = gf_bs_read_int(bs, 8);
846 		nbBytes += 5;
847 	}
848 
849 	while (nbBytes < DescSize) {
850 		GF_Descriptor *tmp = NULL;
851 		e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
852 		if (e) return e;
853 		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
854 		e = AddDescriptorToIsomIOD(iod, tmp);
855 		if (e) return e;
856 		nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
857 	}
858 	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
859 	return GF_OK;
860 }
861 
gf_odf_size_isom_iod(GF_IsomInitialObjectDescriptor * iod,u32 * outSize)862 GF_Err gf_odf_size_isom_iod(GF_IsomInitialObjectDescriptor *iod, u32 *outSize)
863 {
864 	GF_Err e;
865 	if (!iod) return GF_BAD_PARAM;
866 
867 	*outSize = 2;
868 	if (iod->URLString) {
869 		*outSize += gf_odf_size_url_string(iod->URLString);
870 	}
871 	else {
872 		*outSize += 5;
873 		e = gf_odf_size_descriptor_list(iod->ES_ID_IncDescriptors, outSize);
874 		if (e) return e;
875 		e = gf_odf_size_descriptor_list(iod->ES_ID_RefDescriptors, outSize);
876 		if (e) return e;
877 		e = gf_odf_size_descriptor_list(iod->OCIDescriptors, outSize);
878 		if (e) return e;
879 		e = gf_odf_size_descriptor_list(iod->IPMP_Descriptors, outSize);
880 		if (e) return e;
881 	}
882 	if (iod->IPMPToolList) {
883 		u32 tmpSize;
884 		e = gf_odf_size_descriptor((GF_Descriptor *)iod->IPMPToolList, &tmpSize);
885 		if (e) return e;
886 		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
887 	}
888 	return gf_odf_size_descriptor_list(iod->extensionDescriptors, outSize);
889 }
890 
gf_odf_write_isom_iod(GF_BitStream * bs,GF_IsomInitialObjectDescriptor * iod)891 GF_Err gf_odf_write_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *iod)
892 {
893 	GF_Err e;
894 	u32 size;
895 	if (!iod) return GF_BAD_PARAM;
896 
897 	e = gf_odf_size_descriptor((GF_Descriptor *)iod, &size);
898 	if (e) return e;
899 	e = gf_odf_write_base_descriptor(bs, iod->tag, size);
900 	if (e) return e;
901 
902 	gf_bs_write_int(bs, iod->objectDescriptorID, 10);
903 	gf_bs_write_int(bs, iod->URLString != NULL ? 1 : 0, 1);
904 	gf_bs_write_int(bs, iod->inlineProfileFlag, 1);
905 	gf_bs_write_int(bs, 15, 4);		//reserved: 0b1111 == 15
906 
907 	if (iod->URLString) {
908 		gf_odf_write_url_string(bs, iod->URLString);
909 	}
910 	else {
911 		gf_bs_write_int(bs, iod->OD_profileAndLevel, 8);
912 		gf_bs_write_int(bs, iod->scene_profileAndLevel, 8);
913 		gf_bs_write_int(bs, iod->audio_profileAndLevel, 8);
914 		gf_bs_write_int(bs, iod->visual_profileAndLevel, 8);
915 		gf_bs_write_int(bs, iod->graphics_profileAndLevel, 8);
916 		e = gf_odf_write_descriptor_list(bs, iod->ES_ID_IncDescriptors);
917 		if (e) return e;
918 		e = gf_odf_write_descriptor_list(bs, iod->ES_ID_RefDescriptors);
919 		if (e) return e;
920 		e = gf_odf_write_descriptor_list(bs, iod->OCIDescriptors);
921 		if (e) return e;
922 		e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
923 		if (e) return e;
924 		e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_TAG);
925 		if (e) return e;
926 		if (iod->IPMPToolList) {
927 			e = gf_odf_write_descriptor(bs, (GF_Descriptor *)iod->IPMPToolList);
928 			if (e) return e;
929 		}
930 	}
931 	e = gf_odf_write_descriptor_list(bs, iod->extensionDescriptors);
932 	if (e) return e;
933 	return GF_OK;
934 }
935 
936 
gf_odf_new_isom_od()937 GF_Descriptor *gf_odf_new_isom_od()
938 {
939 	GF_IsomObjectDescriptor *newDesc = (GF_IsomObjectDescriptor *)gf_malloc(sizeof(GF_IsomObjectDescriptor));
940 	if (!newDesc) return NULL;
941 
942 	newDesc->URLString = NULL;
943 	newDesc->ES_ID_IncDescriptors = gf_list_new();
944 	newDesc->ES_ID_RefDescriptors = gf_list_new();
945 	newDesc->OCIDescriptors = gf_list_new();
946 	newDesc->IPMP_Descriptors = gf_list_new();
947 	newDesc->extensionDescriptors = gf_list_new();
948 	newDesc->objectDescriptorID = 0;
949 	newDesc->tag = GF_ODF_ISOM_OD_TAG;
950 	return (GF_Descriptor *)newDesc;
951 }
952 
gf_odf_del_isom_od(GF_IsomObjectDescriptor * od)953 GF_Err gf_odf_del_isom_od(GF_IsomObjectDescriptor *od)
954 {
955 	GF_Err e;
956 	if (!od) return GF_BAD_PARAM;
957 	if (od->URLString)	gf_free(od->URLString);
958 	e = gf_odf_delete_descriptor_list(od->ES_ID_IncDescriptors);
959 	if (e) return e;
960 	e = gf_odf_delete_descriptor_list(od->ES_ID_RefDescriptors);
961 	if (e) return e;
962 	e = gf_odf_delete_descriptor_list(od->OCIDescriptors);
963 	if (e) return e;
964 	e = gf_odf_delete_descriptor_list(od->IPMP_Descriptors);
965 	if (e) return e;
966 	e = gf_odf_delete_descriptor_list(od->extensionDescriptors);
967 	if (e) return e;
968 	gf_free(od);
969 	return GF_OK;
970 }
971 
AddDescriptorToIsomOD(GF_IsomObjectDescriptor * od,GF_Descriptor * desc)972 GF_Err AddDescriptorToIsomOD(GF_IsomObjectDescriptor *od, GF_Descriptor *desc)
973 {
974 	if (!od || !desc) return GF_BAD_PARAM;
975 
976 	//check if we can handle ContentClassif tags
977 	if ((desc->tag >= GF_ODF_OCI_BEGIN_TAG) &&
978 		(desc->tag <= GF_ODF_OCI_END_TAG)) {
979 		return gf_list_add(od->OCIDescriptors, desc);
980 	}
981 
982 	//or extension ...
983 	if ((desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
984 		(desc->tag <= GF_ODF_EXT_END_TAG)) {
985 		return gf_list_add(od->extensionDescriptors, desc);
986 	}
987 
988 	switch (desc->tag) {
989 	case GF_ODF_ESD_TAG:
990 		return GF_ODF_FORBIDDEN_DESCRIPTOR;
991 
992 	case GF_ODF_ESD_INC_TAG:
993 		//there shouldn't be ref if inc
994 		if (gf_list_count(od->ES_ID_RefDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
995 		return gf_list_add(od->ES_ID_IncDescriptors, desc);
996 
997 	case GF_ODF_ESD_REF_TAG:
998 		//there shouldn't be inc if ref
999 		if (gf_list_count(od->ES_ID_IncDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
1000 		return gf_list_add(od->ES_ID_RefDescriptors, desc);
1001 
1002 		//we use the same struct for v1 and v2 IPMP DPs
1003 	case GF_ODF_IPMP_PTR_TAG:
1004 	case GF_ODF_IPMP_TAG:
1005 		return gf_list_add(od->IPMP_Descriptors, desc);
1006 
1007 	default:
1008 		return GF_BAD_PARAM;
1009 	}
1010 }
1011 
gf_odf_read_isom_od(GF_BitStream * bs,GF_IsomObjectDescriptor * od,u32 DescSize)1012 GF_Err gf_odf_read_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od, u32 DescSize)
1013 {
1014 	GF_Err e;
1015 	u32 urlflag;
1016 	u32 tmpSize, nbBytes = 0;
1017 	if (!od) return GF_BAD_PARAM;
1018 
1019 	od->objectDescriptorID = gf_bs_read_int(bs, 10);
1020 	urlflag = gf_bs_read_int(bs, 1);
1021 	/*reserved = */gf_bs_read_int(bs, 5);
1022 	nbBytes += 2;
1023 
1024 	if (urlflag) {
1025 		u32 read;
1026 		e = gf_odf_read_url_string(bs, &od->URLString, &read);
1027 		if (e) return e;
1028 		nbBytes += read;
1029 	}
1030 
1031 	while (nbBytes < DescSize) {
1032 		GF_Descriptor *tmp = NULL;
1033 		e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
1034 		if (e) return e;
1035 		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
1036 		e = AddDescriptorToIsomOD(od, tmp);
1037 		if (e) return e;
1038 		nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
1039 	}
1040 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1041 	return GF_OK;
1042 }
1043 
gf_odf_size_isom_od(GF_IsomObjectDescriptor * od,u32 * outSize)1044 GF_Err gf_odf_size_isom_od(GF_IsomObjectDescriptor *od, u32 *outSize)
1045 {
1046 	GF_Err e;
1047 	if (!od) return GF_BAD_PARAM;
1048 
1049 	*outSize = 2;
1050 	if (od->URLString) {
1051 		*outSize += gf_odf_size_url_string(od->URLString);
1052 	}
1053 	else {
1054 		e = gf_odf_size_descriptor_list(od->ES_ID_IncDescriptors, outSize);
1055 		if (e) return e;
1056 		e = gf_odf_size_descriptor_list(od->ES_ID_RefDescriptors, outSize);
1057 		if (e) return e;
1058 		e = gf_odf_size_descriptor_list(od->OCIDescriptors, outSize);
1059 		if (e) return e;
1060 		e = gf_odf_size_descriptor_list(od->IPMP_Descriptors, outSize);
1061 		if (e) return e;
1062 	}
1063 	return gf_odf_size_descriptor_list(od->extensionDescriptors, outSize);
1064 }
1065 
gf_odf_write_isom_od(GF_BitStream * bs,GF_IsomObjectDescriptor * od)1066 GF_Err gf_odf_write_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od)
1067 {
1068 	GF_Err e;
1069 	u32 size;
1070 	if (!od) return GF_BAD_PARAM;
1071 
1072 	e = gf_odf_size_descriptor((GF_Descriptor *)od, &size);
1073 	if (e) return e;
1074 	e = gf_odf_write_base_descriptor(bs, od->tag, size);
1075 	if (e) return e;
1076 
1077 	gf_bs_write_int(bs, od->objectDescriptorID, 10);
1078 	gf_bs_write_int(bs, od->URLString != NULL ? 1 : 0, 1);
1079 	gf_bs_write_int(bs, 31, 5);		//reserved: 0b1111.1 == 31
1080 
1081 	if (od->URLString) {
1082 		gf_odf_write_url_string(bs, od->URLString);
1083 	}
1084 	else {
1085 		e = gf_odf_write_descriptor_list(bs, od->ES_ID_IncDescriptors);
1086 		if (e) return e;
1087 		e = gf_odf_write_descriptor_list(bs, od->ES_ID_RefDescriptors);
1088 		if (e) return e;
1089 		e = gf_odf_write_descriptor_list(bs, od->OCIDescriptors);
1090 		if (e) return e;
1091 		e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
1092 		if (e) return e;
1093 		e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_TAG);
1094 		if (e) return e;
1095 	}
1096 	e = gf_odf_write_descriptor_list(bs, od->extensionDescriptors);
1097 	if (e) return e;
1098 	return GF_OK;
1099 }
1100 
1101 
1102 
gf_odf_new_dcd()1103 GF_Descriptor *gf_odf_new_dcd()
1104 {
1105 	GF_DecoderConfig *newDesc;
1106 	GF_SAFEALLOC(newDesc, GF_DecoderConfig);
1107 	if (!newDesc) return NULL;
1108 
1109 	newDesc->profileLevelIndicationIndexDescriptor = gf_list_new();
1110 	newDesc->tag = GF_ODF_DCD_TAG;
1111 	return (GF_Descriptor *)newDesc;
1112 }
1113 
gf_odf_del_dcd(GF_DecoderConfig * dcd)1114 GF_Err gf_odf_del_dcd(GF_DecoderConfig *dcd)
1115 {
1116 	GF_Err e;
1117 	if (!dcd) return GF_BAD_PARAM;
1118 
1119 	if (dcd->decoderSpecificInfo) {
1120 		e = gf_odf_delete_descriptor((GF_Descriptor *)dcd->decoderSpecificInfo);
1121 		if (e) return e;
1122 	}
1123 	if (dcd->rvc_config) {
1124 		e = gf_odf_delete_descriptor((GF_Descriptor *)dcd->rvc_config);
1125 		if (e) return e;
1126 	}
1127 	e = gf_odf_delete_descriptor_list(dcd->profileLevelIndicationIndexDescriptor);
1128 	if (e) return e;
1129 	gf_free(dcd);
1130 	return GF_OK;
1131 }
1132 
gf_odf_read_dcd(GF_BitStream * bs,GF_DecoderConfig * dcd,u32 DescSize)1133 GF_Err gf_odf_read_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd, u32 DescSize)
1134 {
1135 	GF_Err e;
1136 	u32 /*reserved, */tmp_size, nbBytes = 0;
1137 	if (!dcd) return GF_BAD_PARAM;
1138 
1139 	dcd->objectTypeIndication = gf_bs_read_int(bs, 8);
1140 	dcd->streamType = gf_bs_read_int(bs, 6);
1141 	dcd->upstream = gf_bs_read_int(bs, 1);
1142 	/*reserved = */gf_bs_read_int(bs, 1);
1143 	dcd->bufferSizeDB = gf_bs_read_int(bs, 24);
1144 	dcd->maxBitrate = gf_bs_read_int(bs, 32);
1145 	dcd->avgBitrate = gf_bs_read_int(bs, 32);
1146 	nbBytes += 13;
1147 
1148 	while (nbBytes < DescSize) {
1149 		GF_Descriptor *tmp = NULL;
1150 		e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
1151 		if (e) return e;
1152 		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
1153 		switch (tmp->tag) {
1154 		case GF_ODF_DSI_TAG:
1155 			if (dcd->decoderSpecificInfo) {
1156 				gf_odf_delete_descriptor(tmp);
1157 				return GF_ODF_INVALID_DESCRIPTOR;
1158 			}
1159 			dcd->decoderSpecificInfo = (GF_DefaultDescriptor *)tmp;
1160 			break;
1161 
1162 		case GF_ODF_EXT_PL_TAG:
1163 			e = gf_list_add(dcd->profileLevelIndicationIndexDescriptor, tmp);
1164 			if (e < GF_OK) {
1165 				gf_odf_delete_descriptor(tmp);
1166 				return e;
1167 			}
1168 			break;
1169 
1170 			/*iPod fix: delete and aborts, this will create an InvalidDescriptor at the ESD level with a loaded DSI,
1171 			loading will abort with a partially valid ESD which is all the matters*/
1172 		case GF_ODF_SLC_TAG:
1173 			gf_odf_delete_descriptor(tmp);
1174 			return GF_OK;
1175 
1176 			//what the hell is this descriptor ?? Don't know, so delete it !
1177 		default:
1178 			gf_odf_delete_descriptor(tmp);
1179 			break;
1180 		}
1181 		nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
1182 	}
1183 	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1184 	return GF_OK;
1185 }
1186 
gf_odf_size_dcd(GF_DecoderConfig * dcd,u32 * outSize)1187 GF_Err gf_odf_size_dcd(GF_DecoderConfig *dcd, u32 *outSize)
1188 {
1189 	GF_Err e;
1190 	u32 tmpSize;
1191 	if (!dcd) return GF_BAD_PARAM;
1192 
1193 	*outSize = 0;
1194 	*outSize += 13;
1195 	if (dcd->decoderSpecificInfo) {
1196 		//warning: we don't know anything about the structure of a generic DecSpecInfo
1197 		//we check the tag and size of the descriptor, but we most ofthe time can't parse it
1198 		//the decSpecInfo is handle as a defaultDescriptor (opaque data, but same structure....)
1199 		e = gf_odf_size_descriptor((GF_Descriptor *)dcd->decoderSpecificInfo, &tmpSize);
1200 		if (e) return e;
1201 		*outSize += tmpSize + gf_odf_size_field_size(tmpSize);
1202 	}
1203 	e = gf_odf_size_descriptor_list(dcd->profileLevelIndicationIndexDescriptor, outSize);
1204 	if (e) return e;
1205 	return GF_OK;
1206 }
1207 
gf_odf_write_dcd(GF_BitStream * bs,GF_DecoderConfig * dcd)1208 GF_Err gf_odf_write_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd)
1209 {
1210 	GF_Err e;
1211 	u32 size;
1212 	if (!dcd) return GF_BAD_PARAM;
1213 
1214 	e = gf_odf_size_descriptor((GF_Descriptor *)dcd, &size);
1215 	if (e) return e;
1216 	e = gf_odf_write_base_descriptor(bs, dcd->tag, size);
1217 	if (e) return e;
1218 
1219 	gf_bs_write_int(bs, dcd->objectTypeIndication, 8);
1220 	gf_bs_write_int(bs, dcd->streamType, 6);
1221 	gf_bs_write_int(bs, dcd->upstream, 1);
1222 	gf_bs_write_int(bs, 1, 1);	//reserved field...
1223 	gf_bs_write_int(bs, dcd->bufferSizeDB, 24);
1224 	gf_bs_write_int(bs, dcd->maxBitrate, 32);
1225 	gf_bs_write_int(bs, dcd->avgBitrate, 32);
1226 
1227 	if (dcd->decoderSpecificInfo) {
1228 		e = gf_odf_write_descriptor(bs, (GF_Descriptor *)dcd->decoderSpecificInfo);
1229 		if (e) return e;
1230 	}
1231 	e = gf_odf_write_descriptor_list(bs, dcd->profileLevelIndicationIndexDescriptor);
1232 	return e;
1233 }
1234 
1235 
gf_odf_new_default()1236 GF_Descriptor *gf_odf_new_default()
1237 {
1238 	GF_DefaultDescriptor *newDesc = (GF_DefaultDescriptor *)gf_malloc(sizeof(GF_DefaultDescriptor));
1239 	if (!newDesc) return NULL;
1240 
1241 	newDesc->dataLength = 0;
1242 	newDesc->data = NULL;
1243 	//set it to the Max allowed
1244 	newDesc->tag = GF_ODF_USER_END_TAG;
1245 	return (GF_Descriptor *)newDesc;
1246 }
1247 
gf_odf_del_default(GF_DefaultDescriptor * dd)1248 GF_Err gf_odf_del_default(GF_DefaultDescriptor *dd)
1249 {
1250 	if (!dd) return GF_BAD_PARAM;
1251 
1252 	if (dd->data) gf_free(dd->data);
1253 	gf_free(dd);
1254 	return GF_OK;
1255 }
1256 
gf_odf_read_default(GF_BitStream * bs,GF_DefaultDescriptor * dd,u32 DescSize)1257 GF_Err gf_odf_read_default(GF_BitStream *bs, GF_DefaultDescriptor *dd, u32 DescSize)
1258 {
1259 	u32 nbBytes = 0;
1260 	if (!dd) return GF_BAD_PARAM;
1261 
1262 	dd->dataLength = DescSize;
1263 	dd->data = NULL;
1264 	if (DescSize) {
1265 		dd->data = (char*)gf_malloc(dd->dataLength);
1266 		if (!dd->data) return GF_OUT_OF_MEM;
1267 		gf_bs_read_data(bs, dd->data, dd->dataLength);
1268 		nbBytes += dd->dataLength;
1269 	}
1270 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1271 	return GF_OK;
1272 }
1273 
gf_odf_size_default(GF_DefaultDescriptor * dd,u32 * outSize)1274 GF_Err gf_odf_size_default(GF_DefaultDescriptor *dd, u32 *outSize)
1275 {
1276 	if (!dd) return GF_BAD_PARAM;
1277 	*outSize = dd->dataLength;
1278 	return GF_OK;
1279 }
1280 
gf_odf_write_default(GF_BitStream * bs,GF_DefaultDescriptor * dd)1281 GF_Err gf_odf_write_default(GF_BitStream *bs, GF_DefaultDescriptor *dd)
1282 {
1283 	GF_Err e;
1284 	u32 size;
1285 	if (!dd) return GF_BAD_PARAM;
1286 
1287 	e = gf_odf_size_descriptor((GF_Descriptor *)dd, &size);
1288 	if (e) return e;
1289 	e = gf_odf_write_base_descriptor(bs, dd->tag, size);
1290 	if (e) return e;
1291 
1292 	if (dd->data) {
1293 		gf_bs_write_data(bs, dd->data, dd->dataLength);
1294 	}
1295 	return GF_OK;
1296 }
1297 
gf_odf_new_esd_inc()1298 GF_Descriptor *gf_odf_new_esd_inc()
1299 {
1300 	GF_ES_ID_Inc *newDesc = (GF_ES_ID_Inc *)gf_malloc(sizeof(GF_ES_ID_Inc));
1301 	if (!newDesc) return NULL;
1302 	newDesc->tag = GF_ODF_ESD_INC_TAG;
1303 	newDesc->trackID = 0;
1304 	return (GF_Descriptor *)newDesc;
1305 }
1306 
gf_odf_del_esd_inc(GF_ES_ID_Inc * esd_inc)1307 GF_Err gf_odf_del_esd_inc(GF_ES_ID_Inc *esd_inc)
1308 {
1309 	if (!esd_inc) return GF_BAD_PARAM;
1310 	gf_free(esd_inc);
1311 	return GF_OK;
1312 }
gf_odf_read_esd_inc(GF_BitStream * bs,GF_ES_ID_Inc * esd_inc,u32 DescSize)1313 GF_Err gf_odf_read_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc, u32 DescSize)
1314 {
1315 	u32 nbBytes = 0;
1316 	if (!esd_inc) return GF_BAD_PARAM;
1317 
1318 	esd_inc->trackID = gf_bs_read_int(bs, 32);
1319 	nbBytes += 4;
1320 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1321 	return GF_OK;
1322 }
gf_odf_size_esd_inc(GF_ES_ID_Inc * esd_inc,u32 * outSize)1323 GF_Err gf_odf_size_esd_inc(GF_ES_ID_Inc *esd_inc, u32 *outSize)
1324 {
1325 	if (!esd_inc) return GF_BAD_PARAM;
1326 	*outSize = 4;
1327 	return GF_OK;
1328 }
gf_odf_write_esd_inc(GF_BitStream * bs,GF_ES_ID_Inc * esd_inc)1329 GF_Err gf_odf_write_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc)
1330 {
1331 	GF_Err e;
1332 	u32 size;
1333 	if (!esd_inc) return GF_BAD_PARAM;
1334 
1335 	e = gf_odf_size_descriptor((GF_Descriptor *)esd_inc, &size);
1336 	if (e) return e;
1337 	e = gf_odf_write_base_descriptor(bs, esd_inc->tag, size);
1338 	if (e) return e;
1339 	gf_bs_write_int(bs, esd_inc->trackID, 32);
1340 	return GF_OK;
1341 }
1342 
gf_odf_new_esd_ref()1343 GF_Descriptor *gf_odf_new_esd_ref()
1344 {
1345 	GF_ES_ID_Ref *newDesc = (GF_ES_ID_Ref *)gf_malloc(sizeof(GF_ES_ID_Ref));
1346 	if (!newDesc) return NULL;
1347 	newDesc->tag = GF_ODF_ESD_REF_TAG;
1348 	newDesc->trackRef = 0;
1349 	return (GF_Descriptor *)newDesc;
1350 }
1351 
gf_odf_del_esd_ref(GF_ES_ID_Ref * esd_ref)1352 GF_Err gf_odf_del_esd_ref(GF_ES_ID_Ref *esd_ref)
1353 {
1354 	if (!esd_ref) return GF_BAD_PARAM;
1355 	gf_free(esd_ref);
1356 	return GF_OK;
1357 }
gf_odf_read_esd_ref(GF_BitStream * bs,GF_ES_ID_Ref * esd_ref,u32 DescSize)1358 GF_Err gf_odf_read_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref, u32 DescSize)
1359 {
1360 	u32 nbBytes = 0;
1361 	if (!esd_ref) return GF_BAD_PARAM;
1362 
1363 	esd_ref->trackRef = gf_bs_read_int(bs, 16);
1364 	nbBytes += 2;
1365 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1366 	return GF_OK;
1367 }
1368 
gf_odf_size_esd_ref(GF_ES_ID_Ref * esd_ref,u32 * outSize)1369 GF_Err gf_odf_size_esd_ref(GF_ES_ID_Ref *esd_ref, u32 *outSize)
1370 {
1371 	if (!esd_ref) return GF_BAD_PARAM;
1372 	*outSize = 2;
1373 	return GF_OK;
1374 }
gf_odf_write_esd_ref(GF_BitStream * bs,GF_ES_ID_Ref * esd_ref)1375 GF_Err gf_odf_write_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref)
1376 {
1377 	GF_Err e;
1378 	u32 size;
1379 	if (!esd_ref) return GF_BAD_PARAM;
1380 
1381 	e = gf_odf_size_descriptor((GF_Descriptor *)esd_ref, &size);
1382 	if (e) return e;
1383 	e = gf_odf_write_base_descriptor(bs, esd_ref->tag, size);
1384 	if (e) return e;
1385 
1386 	gf_bs_write_int(bs, esd_ref->trackRef, 16);
1387 	return GF_OK;
1388 }
1389 
1390 
1391 
gf_odf_new_segment()1392 GF_Descriptor *gf_odf_new_segment()
1393 {
1394 	GF_Segment *newDesc = (GF_Segment *)gf_malloc(sizeof(GF_Segment));
1395 	if (!newDesc) return NULL;
1396 
1397 	memset(newDesc, 0, sizeof(GF_Segment));
1398 	newDesc->tag = GF_ODF_SEGMENT_TAG;
1399 	return (GF_Descriptor *)newDesc;
1400 }
1401 
gf_odf_del_segment(GF_Segment * sd)1402 GF_Err gf_odf_del_segment(GF_Segment *sd)
1403 {
1404 	if (!sd) return GF_BAD_PARAM;
1405 
1406 	if (sd->SegmentName) gf_free(sd->SegmentName);
1407 	gf_free(sd);
1408 	return GF_OK;
1409 }
1410 
gf_odf_read_segment(GF_BitStream * bs,GF_Segment * sd,u32 DescSize)1411 GF_Err gf_odf_read_segment(GF_BitStream *bs, GF_Segment *sd, u32 DescSize)
1412 {
1413 	u32 size, nbBytes = 0;
1414 	if (!sd) return GF_BAD_PARAM;
1415 
1416 	sd->startTime = gf_bs_read_double(bs);
1417 	sd->Duration = gf_bs_read_double(bs);
1418 	nbBytes += 16;
1419 	size = gf_bs_read_int(bs, 8);
1420 	nbBytes += 1;
1421 	if (size) {
1422 		sd->SegmentName = (char*)gf_malloc(sizeof(char)*(size + 1));
1423 		if (!sd->SegmentName) return GF_OUT_OF_MEM;
1424 		gf_bs_read_data(bs, sd->SegmentName, size);
1425 		sd->SegmentName[size] = 0;
1426 		nbBytes += size;
1427 	}
1428 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1429 	return GF_OK;
1430 }
1431 
gf_odf_size_segment(GF_Segment * sd,u32 * outSize)1432 GF_Err gf_odf_size_segment(GF_Segment *sd, u32 *outSize)
1433 {
1434 	if (!sd) return GF_BAD_PARAM;
1435 	*outSize = 17;
1436 	if (sd->SegmentName) *outSize += (u32)strlen(sd->SegmentName);
1437 	return GF_OK;
1438 }
1439 
gf_odf_write_segment(GF_BitStream * bs,GF_Segment * sd)1440 GF_Err gf_odf_write_segment(GF_BitStream *bs, GF_Segment *sd)
1441 {
1442 	GF_Err e;
1443 	u32 size;
1444 	if (!sd) return GF_BAD_PARAM;
1445 	e = gf_odf_size_descriptor((GF_Descriptor *)sd, &size);
1446 	if (e) return e;
1447 	e = gf_odf_write_base_descriptor(bs, sd->tag, size);
1448 	if (e) return e;
1449 	gf_bs_write_double(bs, sd->startTime);
1450 	gf_bs_write_double(bs, sd->Duration);
1451 	if (sd->SegmentName) {
1452 		gf_bs_write_int(bs, (u32)strlen(sd->SegmentName), 8);
1453 		gf_bs_write_data(bs, sd->SegmentName, (u32)strlen(sd->SegmentName));
1454 	}
1455 	else {
1456 		gf_bs_write_int(bs, 0, 8);
1457 	}
1458 	return GF_OK;
1459 }
gf_odf_new_mediatime()1460 GF_Descriptor *gf_odf_new_mediatime()
1461 {
1462 	GF_MediaTime *newDesc = (GF_MediaTime *)gf_malloc(sizeof(GF_MediaTime));
1463 	if (!newDesc) return NULL;
1464 
1465 	memset(newDesc, 0, sizeof(GF_MediaTime));
1466 	newDesc->tag = GF_ODF_MEDIATIME_TAG;
1467 	return (GF_Descriptor *)newDesc;
1468 }
gf_odf_del_mediatime(GF_MediaTime * mt)1469 GF_Err gf_odf_del_mediatime(GF_MediaTime *mt)
1470 {
1471 	if (!mt) return GF_BAD_PARAM;
1472 	gf_free(mt);
1473 	return GF_OK;
1474 }
gf_odf_read_mediatime(GF_BitStream * bs,GF_MediaTime * mt,u32 DescSize)1475 GF_Err gf_odf_read_mediatime(GF_BitStream *bs, GF_MediaTime *mt, u32 DescSize)
1476 {
1477 	if (!mt) return GF_BAD_PARAM;
1478 	mt->mediaTimeStamp = gf_bs_read_double(bs);
1479 	return GF_OK;
1480 }
gf_odf_size_mediatime(GF_MediaTime * mt,u32 * outSize)1481 GF_Err gf_odf_size_mediatime(GF_MediaTime *mt, u32 *outSize)
1482 {
1483 	if (!mt) return GF_BAD_PARAM;
1484 	*outSize = 8;
1485 	return GF_OK;
1486 }
gf_odf_write_mediatime(GF_BitStream * bs,GF_MediaTime * mt)1487 GF_Err gf_odf_write_mediatime(GF_BitStream *bs, GF_MediaTime *mt)
1488 {
1489 	GF_Err e;
1490 	u32 size;
1491 	if (!mt) return GF_BAD_PARAM;
1492 	e = gf_odf_size_descriptor((GF_Descriptor *)mt, &size);
1493 	if (e) return e;
1494 	e = gf_odf_write_base_descriptor(bs, mt->tag, size);
1495 	if (e) return e;
1496 	gf_bs_write_double(bs, mt->mediaTimeStamp);
1497 	return GF_OK;
1498 }
1499 
1500 
gf_odf_new_lang()1501 GF_Descriptor *gf_odf_new_lang()
1502 {
1503 	GF_Language *newDesc;
1504 	GF_SAFEALLOC(newDesc, GF_Language);
1505 	if (!newDesc) return NULL;
1506 	newDesc->tag = GF_ODF_LANG_TAG;
1507 	return (GF_Descriptor *)newDesc;
1508 }
1509 
gf_odf_del_lang(GF_Language * ld)1510 GF_Err gf_odf_del_lang(GF_Language *ld)
1511 {
1512 	if (!ld) return GF_BAD_PARAM;
1513 	if (ld->full_lang_code) gf_free(ld->full_lang_code);
1514 	gf_free(ld);
1515 	return GF_OK;
1516 }
1517 
gf_odf_read_lang(GF_BitStream * bs,GF_Language * ld,u32 DescSize)1518 GF_Err gf_odf_read_lang(GF_BitStream *bs, GF_Language *ld, u32 DescSize)
1519 {
1520 	u32 nbBytes = 0;
1521 	if (!ld) return GF_BAD_PARAM;
1522 
1523 	ld->langCode = gf_bs_read_int(bs, 24);
1524 	nbBytes += 3;
1525 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
1526 	return GF_OK;
1527 }
1528 
gf_odf_size_lang(GF_Language * ld,u32 * outSize)1529 GF_Err gf_odf_size_lang(GF_Language *ld, u32 *outSize)
1530 {
1531 	if (!ld) return GF_BAD_PARAM;
1532 	*outSize = 3;
1533 	return GF_OK;
1534 }
1535 
gf_odf_write_lang(GF_BitStream * bs,GF_Language * ld)1536 GF_Err gf_odf_write_lang(GF_BitStream *bs, GF_Language *ld)
1537 {
1538 	GF_Err e;
1539 	u32 size;
1540 	if (!ld) return GF_BAD_PARAM;
1541 
1542 	e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size);
1543 	if (e) return e;
1544 	e = gf_odf_write_base_descriptor(bs, ld->tag, size);
1545 	if (e) return e;
1546 	gf_bs_write_int(bs, ld->langCode, 24);
1547 	return GF_OK;
1548 }
1549 
1550 
1551 
gf_odf_new_auxvid()1552 GF_Descriptor *gf_odf_new_auxvid()
1553 {
1554 	GF_AuxVideoDescriptor *newDesc;
1555 	GF_SAFEALLOC(newDesc, GF_AuxVideoDescriptor);
1556 	if (!newDesc) return NULL;
1557 	newDesc->tag = GF_ODF_AUX_VIDEO_DATA;
1558 	return (GF_Descriptor *)newDesc;
1559 }
1560 
gf_odf_del_auxvid(GF_AuxVideoDescriptor * ld)1561 GF_Err gf_odf_del_auxvid(GF_AuxVideoDescriptor *ld)
1562 {
1563 	if (!ld) return GF_BAD_PARAM;
1564 	gf_free(ld);
1565 	return GF_OK;
1566 }
1567 
gf_odf_read_auxvid(GF_BitStream * bs,GF_AuxVideoDescriptor * ld,u32 DescSize)1568 GF_Err gf_odf_read_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld, u32 DescSize)
1569 {
1570 	u32 nbBytes = 0;
1571 	if (!ld) return GF_BAD_PARAM;
1572 
1573 	ld->aux_video_type = gf_bs_read_int(bs, 8);
1574 	ld->position_offset_h = gf_bs_read_int(bs, 8);
1575 	ld->position_offset_v = gf_bs_read_int(bs, 8);
1576 	nbBytes += 3;
1577 	switch (ld->aux_video_type) {
1578 	case 0x10:
1579 		ld->kfar = gf_bs_read_int(bs, 8);
1580 		ld->knear = gf_bs_read_int(bs, 8);
1581 		nbBytes += 2;
1582 		break;
1583 	case 0x11:
1584 		ld->parallax_zero = gf_bs_read_int(bs, 16);
1585 		ld->parallax_scale = gf_bs_read_int(bs, 16);
1586 		ld->dref = gf_bs_read_int(bs, 16);
1587 		ld->wref = gf_bs_read_int(bs, 16);
1588 		nbBytes += 8;
1589 		break;
1590 	}
1591 	while (nbBytes < DescSize) {
1592 		gf_bs_read_int(bs, 8);
1593 		nbBytes++;
1594 	}
1595 	return GF_OK;
1596 }
1597 
gf_odf_size_auxvid(GF_AuxVideoDescriptor * ld,u32 * outSize)1598 GF_Err gf_odf_size_auxvid(GF_AuxVideoDescriptor *ld, u32 *outSize)
1599 {
1600 	if (!ld) return GF_BAD_PARAM;
1601 	switch (ld->aux_video_type) {
1602 	case 0x10:
1603 		*outSize = 5;
1604 		break;
1605 	case 0x11:
1606 		*outSize = 11;
1607 		break;
1608 	default:
1609 		*outSize = 3;
1610 		break;
1611 	}
1612 	return GF_OK;
1613 }
1614 
gf_odf_write_auxvid(GF_BitStream * bs,GF_AuxVideoDescriptor * ld)1615 GF_Err gf_odf_write_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld)
1616 {
1617 	GF_Err e;
1618 	u32 size;
1619 	if (!ld) return GF_BAD_PARAM;
1620 	e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size);
1621 	if (e) return e;
1622 	e = gf_odf_write_base_descriptor(bs, ld->tag, size);
1623 	if (e) return e;
1624 
1625 	gf_bs_write_int(bs, ld->aux_video_type, 8);
1626 	gf_bs_write_int(bs, ld->position_offset_h, 8);
1627 	gf_bs_write_int(bs, ld->position_offset_v, 8);
1628 	switch (ld->aux_video_type) {
1629 	case 0x10:
1630 		gf_bs_write_int(bs, ld->kfar, 8);
1631 		gf_bs_write_int(bs, ld->knear, 8);
1632 		break;
1633 	case 0x11:
1634 		gf_bs_write_int(bs, ld->parallax_zero, 16);
1635 		gf_bs_write_int(bs, ld->parallax_scale, 16);
1636 		gf_bs_write_int(bs, ld->dref, 16);
1637 		gf_bs_write_int(bs, ld->wref, 16);
1638 		break;
1639 	}
1640 	return GF_OK;
1641 }
1642 
1643 
1644 
gf_odf_new_muxinfo()1645 GF_Descriptor *gf_odf_new_muxinfo()
1646 {
1647 	GF_MuxInfo *newDesc = (GF_MuxInfo *)gf_malloc(sizeof(GF_MuxInfo));
1648 	if (!newDesc) return NULL;
1649 	memset(newDesc, 0, sizeof(GF_MuxInfo));
1650 	newDesc->tag = GF_ODF_MUXINFO_TAG;
1651 	return (GF_Descriptor *)newDesc;
1652 }
1653 
gf_odf_del_muxinfo(GF_MuxInfo * mi)1654 GF_Err gf_odf_del_muxinfo(GF_MuxInfo *mi)
1655 {
1656 	if (!mi) return GF_BAD_PARAM;
1657 	if (mi->file_name) gf_free(mi->file_name);
1658 	if (mi->src_url) gf_free(mi->src_url);
1659 	if (mi->streamFormat) gf_free(mi->streamFormat);
1660 	if (mi->textNode) gf_free(mi->textNode);
1661 	if (mi->fontNode) gf_free(mi->fontNode);
1662 	gf_free(mi);
1663 	return GF_OK;
1664 }
1665 
gf_odf_read_muxinfo(GF_BitStream * bs,GF_MuxInfo * mi,u32 DescSize)1666 GF_Err gf_odf_read_muxinfo(GF_BitStream *bs, GF_MuxInfo *mi, u32 DescSize)
1667 {
1668 	return GF_OK;
1669 }
gf_odf_size_muxinfo(GF_MuxInfo * mi,u32 * outSize)1670 GF_Err gf_odf_size_muxinfo(GF_MuxInfo *mi, u32 *outSize)
1671 {
1672 	*outSize = 0;
1673 	return GF_OK;
1674 }
gf_odf_write_muxinfo(GF_BitStream * bs,GF_MuxInfo * mi)1675 GF_Err gf_odf_write_muxinfo(GF_BitStream *bs, GF_MuxInfo *mi)
1676 {
1677 	return GF_OK;
1678 }
1679 
gf_odf_New_ElemMask()1680 GF_Descriptor *gf_odf_New_ElemMask()
1681 {
1682 	GF_ElementaryMask *newDesc = (GF_ElementaryMask*)gf_malloc(sizeof(GF_ElementaryMask));
1683 	if (!newDesc) return NULL;
1684 	memset(newDesc, 0, sizeof(GF_ElementaryMask));
1685 	newDesc->tag = GF_ODF_ELEM_MASK_TAG;
1686 	return (GF_Descriptor *)newDesc;
1687 }
1688 
gf_odf_del_ElemMask(GF_ElementaryMask * desc)1689 GF_Err gf_odf_del_ElemMask(GF_ElementaryMask *desc)
1690 {
1691 	if (desc->node_name) gf_free(desc->node_name);
1692 	gf_free(desc);
1693 	return GF_OK;
1694 }
1695 
gf_odf_new_bifs_cfg()1696 GF_Descriptor *gf_odf_new_bifs_cfg()
1697 {
1698 	GF_BIFSConfig *newDesc = (GF_BIFSConfig *)gf_malloc(sizeof(GF_BIFSConfig));
1699 	if (!newDesc) return NULL;
1700 	memset(newDesc, 0, sizeof(GF_BIFSConfig));
1701 	newDesc->tag = GF_ODF_BIFS_CFG_TAG;
1702 	return (GF_Descriptor *)newDesc;
1703 }
1704 
gf_odf_del_bifs_cfg(GF_BIFSConfig * desc)1705 GF_Err gf_odf_del_bifs_cfg(GF_BIFSConfig *desc)
1706 {
1707 	if (desc->elementaryMasks) {
1708 		u32 i, count = gf_list_count(desc->elementaryMasks);
1709 		for (i = 0; i<count; i++) {
1710 			GF_ElementaryMask *tmp = (GF_ElementaryMask *)gf_list_get(desc->elementaryMasks, i);
1711 			if (tmp->node_name) gf_free(tmp->node_name);
1712 			gf_free(tmp);
1713 		}
1714 		gf_list_del(desc->elementaryMasks);
1715 	}
1716 	gf_free(desc);
1717 	return GF_OK;
1718 }
1719 
gf_odf_new_laser_cfg()1720 GF_Descriptor *gf_odf_new_laser_cfg()
1721 {
1722 	GF_LASERConfig *newDesc = (GF_LASERConfig *)gf_malloc(sizeof(GF_LASERConfig));
1723 	if (!newDesc) return NULL;
1724 	memset(newDesc, 0, sizeof(GF_LASERConfig));
1725 	newDesc->tag = GF_ODF_LASER_CFG_TAG;
1726 	return (GF_Descriptor *)newDesc;
1727 }
1728 
gf_odf_del_laser_cfg(GF_LASERConfig * desc)1729 GF_Err gf_odf_del_laser_cfg(GF_LASERConfig *desc)
1730 {
1731 	gf_free(desc);
1732 	return GF_OK;
1733 }
1734 
gf_odf_new_ui_cfg()1735 GF_Descriptor *gf_odf_new_ui_cfg()
1736 {
1737 	GF_UIConfig *newDesc = (GF_UIConfig *)gf_malloc(sizeof(GF_UIConfig));
1738 	if (!newDesc) return NULL;
1739 	memset(newDesc, 0, sizeof(GF_UIConfig));
1740 	newDesc->tag = GF_ODF_UI_CFG_TAG;
1741 	return (GF_Descriptor *)newDesc;
1742 }
1743 
gf_odf_del_ui_cfg(GF_UIConfig * desc)1744 GF_Err gf_odf_del_ui_cfg(GF_UIConfig *desc)
1745 {
1746 	if (desc->deviceName) gf_free(desc->deviceName);
1747 	if (desc->ui_data) gf_free(desc->ui_data);
1748 	gf_free(desc);
1749 	return GF_OK;
1750 }
1751 
1752 #ifndef GPAC_MINIMAL_ODF
1753 
1754 
1755 
gf_odf_new_cc()1756 GF_Descriptor *gf_odf_new_cc()
1757 {
1758 	GF_CCDescriptor *newDesc = (GF_CCDescriptor *)gf_malloc(sizeof(GF_CCDescriptor));
1759 	if (!newDesc) return NULL;
1760 
1761 	newDesc->contentClassificationData = NULL;
1762 	newDesc->dataLength = 0;
1763 	newDesc->classificationEntity = 0;
1764 	newDesc->classificationTable = 0;
1765 	newDesc->tag = GF_ODF_CC_TAG;
1766 	return (GF_Descriptor *)newDesc;
1767 }
1768 
gf_odf_del_cc(GF_CCDescriptor * ccd)1769 GF_Err gf_odf_del_cc(GF_CCDescriptor *ccd)
1770 {
1771 	if (!ccd) return GF_BAD_PARAM;
1772 	if (ccd->contentClassificationData) gf_free(ccd->contentClassificationData);
1773 	gf_free(ccd);
1774 	return GF_OK;
1775 }
1776 
gf_odf_read_cc(GF_BitStream * bs,GF_CCDescriptor * ccd,u32 DescSize)1777 GF_Err gf_odf_read_cc(GF_BitStream *bs, GF_CCDescriptor *ccd, u32 DescSize)
1778 {
1779 	u32 nbBytes = 0;
1780 	if (!ccd) return GF_BAD_PARAM;
1781 
1782 	ccd->classificationEntity = gf_bs_read_int(bs, 32);
1783 	ccd->classificationTable = gf_bs_read_int(bs, 16);
1784 	nbBytes += 6;
1785 	ccd->dataLength = DescSize - 6;
1786 	ccd->contentClassificationData = (char*)gf_malloc(sizeof(char) * ccd->dataLength);
1787 	if (!ccd->contentClassificationData) return GF_OUT_OF_MEM;
1788 	gf_bs_read_data(bs, ccd->contentClassificationData, ccd->dataLength);
1789 	nbBytes += ccd->dataLength;
1790 
1791 	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1792 	return GF_OK;
1793 }
1794 
gf_odf_size_cc(GF_CCDescriptor * ccd,u32 * outSize)1795 GF_Err gf_odf_size_cc(GF_CCDescriptor *ccd, u32 *outSize)
1796 {
1797 	if (!ccd) return GF_BAD_PARAM;
1798 	*outSize = 6 + ccd->dataLength;
1799 	return GF_OK;
1800 }
1801 
gf_odf_write_cc(GF_BitStream * bs,GF_CCDescriptor * ccd)1802 GF_Err gf_odf_write_cc(GF_BitStream *bs, GF_CCDescriptor *ccd)
1803 {
1804 	u32 size;
1805 	GF_Err e;
1806 	if (!ccd) return GF_BAD_PARAM;
1807 
1808 	e = gf_odf_size_descriptor((GF_Descriptor *)ccd, &size);
1809 	if (e) return e;
1810 	e = gf_odf_write_base_descriptor(bs, ccd->tag, size);
1811 	if (e) return e;
1812 	gf_bs_write_int(bs, ccd->classificationEntity, 32);
1813 	gf_bs_write_int(bs, ccd->classificationTable, 16);
1814 	gf_bs_write_data(bs, ccd->contentClassificationData, ccd->dataLength);
1815 	return GF_OK;
1816 }
1817 
gf_odf_new_cc_date()1818 GF_Descriptor *gf_odf_new_cc_date()
1819 {
1820 	GF_CC_Date *newDesc = (GF_CC_Date *)gf_malloc(sizeof(GF_CC_Date));
1821 	if (!newDesc) return NULL;
1822 	memset(newDesc->contentCreationDate, 0, 5);
1823 	newDesc->tag = GF_ODF_CC_DATE_TAG;
1824 	return (GF_Descriptor *)newDesc;
1825 }
1826 
1827 
gf_odf_del_cc_date(GF_CC_Date * cdd)1828 GF_Err gf_odf_del_cc_date(GF_CC_Date *cdd)
1829 {
1830 	if (!cdd) return GF_BAD_PARAM;
1831 	gf_free(cdd);
1832 	return GF_OK;
1833 }
1834 
gf_odf_read_cc_date(GF_BitStream * bs,GF_CC_Date * cdd,u32 DescSize)1835 GF_Err gf_odf_read_cc_date(GF_BitStream *bs, GF_CC_Date *cdd, u32 DescSize)
1836 {
1837 	u32 nbBytes = 0;
1838 	if (!cdd) return GF_BAD_PARAM;
1839 
1840 	gf_bs_read_data(bs, cdd->contentCreationDate, DATE_CODING_BIT_LEN);
1841 	nbBytes += DATE_CODING_BIT_LEN / 8;
1842 	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1843 	return GF_OK;
1844 }
1845 
gf_odf_size_cc_date(GF_CC_Date * cdd,u32 * outSize)1846 GF_Err gf_odf_size_cc_date(GF_CC_Date *cdd, u32 *outSize)
1847 {
1848 	if (!cdd) return GF_BAD_PARAM;
1849 	*outSize = (DATE_CODING_BIT_LEN / 8);
1850 	return GF_OK;
1851 }
1852 
gf_odf_write_cc_date(GF_BitStream * bs,GF_CC_Date * cdd)1853 GF_Err gf_odf_write_cc_date(GF_BitStream *bs, GF_CC_Date *cdd)
1854 {
1855 	u32 size;
1856 	GF_Err e;
1857 	if (!cdd) return GF_BAD_PARAM;
1858 
1859 	e = gf_odf_size_descriptor((GF_Descriptor *)cdd, &size);
1860 	if (e) return e;
1861 	e = gf_odf_write_base_descriptor(bs, cdd->tag, size);
1862 	if (e) return e;
1863 
1864 	gf_bs_write_data(bs, cdd->contentCreationDate, DATE_CODING_BIT_LEN);
1865 	return GF_OK;
1866 }
1867 
gf_odf_new_cc_name()1868 GF_Descriptor *gf_odf_new_cc_name()
1869 {
1870 	GF_CC_Name *newDesc = (GF_CC_Name *)gf_malloc(sizeof(GF_CC_Name));
1871 	if (!newDesc) return NULL;
1872 
1873 	newDesc->ContentCreators = gf_list_new();
1874 	if (!newDesc->ContentCreators) {
1875 		gf_free(newDesc);
1876 		return NULL;
1877 	}
1878 	newDesc->tag = GF_ODF_CC_NAME_TAG;
1879 	return (GF_Descriptor *)newDesc;
1880 }
1881 
gf_odf_del_cc_name(GF_CC_Name * cnd)1882 GF_Err gf_odf_del_cc_name(GF_CC_Name *cnd)
1883 {
1884 	u32 i;
1885 	GF_ContentCreatorInfo *tmp;
1886 	if (!cnd) return GF_BAD_PARAM;
1887 
1888 	i = 0;
1889 	while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
1890 		if (tmp->contentCreatorName) gf_free(tmp->contentCreatorName);
1891 		gf_free(tmp);
1892 	}
1893 	gf_list_del(cnd->ContentCreators);
1894 	gf_free(cnd);
1895 	return GF_OK;
1896 }
1897 
gf_odf_read_cc_name(GF_BitStream * bs,GF_CC_Name * cnd,u32 DescSize)1898 GF_Err gf_odf_read_cc_name(GF_BitStream *bs, GF_CC_Name *cnd, u32 DescSize)
1899 {
1900 	GF_Err e;
1901 	u32 i, count, len, nbBytes = 0;
1902 	if (!cnd) return GF_BAD_PARAM;
1903 
1904 	count = gf_bs_read_int(bs, 8);
1905 	nbBytes += 1;
1906 	for (i = 0; i< count; i++) {
1907 		GF_ContentCreatorInfo *tmp = (GF_ContentCreatorInfo*)gf_malloc(sizeof(GF_ContentCreatorInfo));
1908 		if (!tmp) return GF_OUT_OF_MEM;
1909 		memset(tmp, 0, sizeof(GF_ContentCreatorInfo));
1910 		tmp->langCode = gf_bs_read_int(bs, 24);
1911 		tmp->isUTF8 = gf_bs_read_int(bs, 1);
1912 		/*aligned = */gf_bs_read_int(bs, 7);
1913 		nbBytes += 4;
1914 
1915 		e = OD_ReadUTF8String(bs, &tmp->contentCreatorName, tmp->isUTF8, &len);
1916 		if (e) return e;
1917 		nbBytes += len;
1918 		e = gf_list_add(cnd->ContentCreators, tmp);
1919 		if (e) return e;
1920 	}
1921 	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
1922 	return GF_OK;
1923 }
1924 
gf_odf_size_cc_name(GF_CC_Name * cnd,u32 * outSize)1925 GF_Err gf_odf_size_cc_name(GF_CC_Name *cnd, u32 *outSize)
1926 {
1927 	u32 i;
1928 	GF_ContentCreatorInfo *tmp;
1929 	if (!cnd) return GF_BAD_PARAM;
1930 
1931 	*outSize = 1;
1932 	i = 0;
1933 	while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
1934 		*outSize += 4 + OD_SizeUTF8String(tmp->contentCreatorName, tmp->isUTF8);
1935 	}
1936 	return GF_OK;
1937 }
1938 
gf_odf_write_cc_name(GF_BitStream * bs,GF_CC_Name * cnd)1939 GF_Err gf_odf_write_cc_name(GF_BitStream *bs, GF_CC_Name *cnd)
1940 {
1941 	GF_Err e;
1942 	GF_ContentCreatorInfo *tmp;
1943 	u32 i, size;
1944 	if (!cnd) return GF_BAD_PARAM;
1945 
1946 	e = gf_odf_size_descriptor((GF_Descriptor *)cnd, &size);
1947 	if (e) return e;
1948 	e = gf_odf_write_base_descriptor(bs, cnd->tag, size);
1949 	if (e) return e;
1950 	gf_bs_write_int(bs, gf_list_count(cnd->ContentCreators), 8);
1951 
1952 	i = 0;
1953 	while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
1954 		gf_bs_write_int(bs, tmp->langCode, 24);
1955 		gf_bs_write_int(bs, tmp->isUTF8, 1);
1956 		gf_bs_write_int(bs, 0, 7);		//aligned
1957 		OD_WriteUTF8String(bs, tmp->contentCreatorName, tmp->isUTF8);
1958 	}
1959 	return GF_OK;
1960 }
1961 
1962 
gf_odf_new_ci()1963 GF_Descriptor *gf_odf_new_ci()
1964 {
1965 	GF_CIDesc *newDesc = (GF_CIDesc *)gf_malloc(sizeof(GF_CIDesc));
1966 	if (!newDesc) return NULL;
1967 
1968 	newDesc->compatibility = 0;
1969 	newDesc->contentIdentifier = NULL;
1970 	newDesc->tag = GF_ODF_CI_TAG;
1971 	newDesc->contentIdentifierFlag = 0;
1972 	newDesc->contentIdentifierType = 0;
1973 	newDesc->contentType = 0;
1974 	newDesc->contentTypeFlag = 0;
1975 	newDesc->protectedContent = 0;
1976 	return (GF_Descriptor *)newDesc;
1977 }
1978 
1979 
gf_odf_del_ci(GF_CIDesc * cid)1980 GF_Err gf_odf_del_ci(GF_CIDesc *cid)
1981 {
1982 	if (!cid) return GF_BAD_PARAM;
1983 
1984 	if (cid->contentIdentifier) gf_free(cid->contentIdentifier);
1985 	gf_free(cid);
1986 	return GF_OK;
1987 }
1988 
1989 
gf_odf_read_ci(GF_BitStream * bs,GF_CIDesc * cid,u32 DescSize)1990 GF_Err gf_odf_read_ci(GF_BitStream *bs, GF_CIDesc *cid, u32 DescSize)
1991 {
1992 	u32 nbBytes = 0;
1993 	if (!cid) return GF_BAD_PARAM;
1994 
1995 	cid->compatibility = gf_bs_read_int(bs, 2);	//MUST BE NULL
1996 	if (cid->compatibility) return GF_ODF_INVALID_DESCRIPTOR;
1997 
1998 	cid->contentTypeFlag = gf_bs_read_int(bs, 1);
1999 	cid->contentIdentifierFlag = gf_bs_read_int(bs, 1);
2000 	cid->protectedContent = gf_bs_read_int(bs, 1);
2001 	/*reserved = */gf_bs_read_int(bs, 3);
2002 	nbBytes += 1;
2003 
2004 	if (cid->contentTypeFlag) {
2005 		cid->contentType = gf_bs_read_int(bs, 8);
2006 		nbBytes += 1;
2007 	}
2008 	if (cid->contentIdentifierFlag) {
2009 		cid->contentIdentifierType = gf_bs_read_int(bs, 8);
2010 		cid->contentIdentifier = (char*)gf_malloc(DescSize - 2 - cid->contentTypeFlag);
2011 		if (!cid->contentIdentifier) return GF_OUT_OF_MEM;
2012 
2013 		gf_bs_read_data(bs, cid->contentIdentifier, DescSize - 2 - cid->contentTypeFlag);
2014 		nbBytes += DescSize - 1 - cid->contentTypeFlag;
2015 	}
2016 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2017 	return GF_OK;
2018 }
2019 
gf_odf_size_ci(GF_CIDesc * cid,u32 * outSize)2020 GF_Err gf_odf_size_ci(GF_CIDesc *cid, u32 *outSize)
2021 {
2022 	if (!cid) return GF_BAD_PARAM;
2023 
2024 	*outSize = 1;
2025 	if (cid->contentTypeFlag) *outSize += 1;
2026 
2027 	if (cid->contentIdentifierFlag)
2028 		*outSize += (u32)strlen((const char*)cid->contentIdentifier) - 1 - cid->contentTypeFlag;
2029 	return GF_OK;
2030 }
2031 
gf_odf_write_ci(GF_BitStream * bs,GF_CIDesc * cid)2032 GF_Err gf_odf_write_ci(GF_BitStream *bs, GF_CIDesc *cid)
2033 {
2034 	GF_Err e;
2035 	u32 size;
2036 	if (!cid) return GF_BAD_PARAM;
2037 
2038 	e = gf_odf_size_descriptor((GF_Descriptor *)cid, &size);
2039 	if (e) return e;
2040 	e = gf_odf_write_base_descriptor(bs, cid->tag, size);
2041 	if (e) return e;
2042 
2043 	gf_bs_write_int(bs, cid->compatibility, 2);
2044 	gf_bs_write_int(bs, cid->contentTypeFlag, 1);
2045 	gf_bs_write_int(bs, cid->contentIdentifierFlag, 1);
2046 	gf_bs_write_int(bs, cid->protectedContent, 1);
2047 	gf_bs_write_int(bs, 7, 3);		//reserved 0b111 = 7
2048 
2049 	if (cid->contentTypeFlag) {
2050 		gf_bs_write_int(bs, cid->contentType, 8);
2051 	}
2052 
2053 	if (cid->contentIdentifierFlag) {
2054 		gf_bs_write_int(bs, cid->contentIdentifierType, 8);
2055 		gf_bs_write_data(bs, cid->contentIdentifier, size - 2 - cid->contentTypeFlag);
2056 	}
2057 	return GF_OK;
2058 }
2059 
gf_odf_new_exp_text()2060 GF_Descriptor *gf_odf_new_exp_text()
2061 {
2062 	GF_ExpandedTextual *newDesc = (GF_ExpandedTextual *)gf_malloc(sizeof(GF_ExpandedTextual));
2063 	if (!newDesc) return NULL;
2064 
2065 	newDesc->itemDescriptionList = gf_list_new();
2066 	if (!newDesc->itemDescriptionList) {
2067 		gf_free(newDesc);
2068 		return NULL;
2069 	}
2070 	newDesc->itemTextList = gf_list_new();
2071 	if (!newDesc->itemTextList) {
2072 		gf_free(newDesc->itemDescriptionList);
2073 		gf_free(newDesc);
2074 		return NULL;
2075 	}
2076 	newDesc->isUTF8 = 0;
2077 	newDesc->langCode = 0;
2078 	newDesc->NonItemText = NULL;
2079 	newDesc->tag = GF_ODF_TEXT_TAG;
2080 	return (GF_Descriptor *)newDesc;
2081 }
2082 
gf_odf_del_exp_text(GF_ExpandedTextual * etd)2083 GF_Err gf_odf_del_exp_text(GF_ExpandedTextual *etd)
2084 {
2085 	if (!etd) return GF_BAD_PARAM;
2086 
2087 	while (gf_list_count(etd->itemDescriptionList)) {
2088 		GF_ETD_ItemText *tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemDescriptionList, 0);
2089 		if (tmp) {
2090 			if (tmp->text) gf_free(tmp->text);
2091 			gf_free(tmp);
2092 		}
2093 		gf_list_rem(etd->itemDescriptionList, 0);
2094 	}
2095 	gf_list_del(etd->itemDescriptionList);
2096 
2097 	while (gf_list_count(etd->itemTextList)) {
2098 		GF_ETD_ItemText *tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, 0);
2099 		if (tmp) {
2100 			if (tmp->text) gf_free(tmp->text);
2101 			gf_free(tmp);
2102 		}
2103 		gf_list_rem(etd->itemTextList, 0);
2104 	}
2105 	gf_list_del(etd->itemTextList);
2106 
2107 	if (etd->NonItemText) gf_free(etd->NonItemText);
2108 	gf_free(etd);
2109 	return GF_OK;
2110 }
2111 
gf_odf_read_exp_text(GF_BitStream * bs,GF_ExpandedTextual * etd,u32 DescSize)2112 GF_Err gf_odf_read_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd, u32 DescSize)
2113 {
2114 	GF_Err e;
2115 	u32 nbBytes = 0;
2116 	u32 i, len, nonLen, count;
2117 	if (!etd) return GF_BAD_PARAM;
2118 
2119 	etd->langCode = gf_bs_read_int(bs, 24);
2120 	etd->isUTF8 = gf_bs_read_int(bs, 1);
2121 	/*aligned = */gf_bs_read_int(bs, 7);
2122 	count = gf_bs_read_int(bs, 8);
2123 	nbBytes += 5;
2124 
2125 	for (i = 0; i< count; i++) {
2126 		//description
2127 		GF_ETD_ItemText *description, *Text;
2128 		description = (GF_ETD_ItemText*)gf_malloc(sizeof(GF_ETD_ItemText));
2129 		if (!description) return GF_OUT_OF_MEM;
2130 		description->text = NULL;
2131 		e = OD_ReadUTF8String(bs, &description->text, etd->isUTF8, &len);
2132 		if (e) return e;
2133 		e = gf_list_add(etd->itemDescriptionList, description);
2134 		if (e) return e;
2135 		nbBytes += len;
2136 
2137 		//text
2138 		Text = (GF_ETD_ItemText*)gf_malloc(sizeof(GF_ETD_ItemText));
2139 		if (!Text) return GF_OUT_OF_MEM;
2140 		Text->text = NULL;
2141 		e = OD_ReadUTF8String(bs, &Text->text, etd->isUTF8, &len);
2142 		if (e) return e;
2143 		e = gf_list_add(etd->itemTextList, Text);
2144 		if (e) return e;
2145 		nbBytes += len;
2146 	}
2147 	len = gf_bs_read_int(bs, 8);
2148 	nbBytes += 1;
2149 	nonLen = 0;
2150 	while (len == 255) {
2151 		nonLen += len;
2152 		len = gf_bs_read_int(bs, 8);
2153 		nbBytes += 1;
2154 	}
2155 	nonLen += len;
2156 	if (nonLen) {
2157 		//here we have no choice but do the job ourselves
2158 		//because the length is not encoded on 8 bits
2159 		etd->NonItemText = (char *)gf_malloc(sizeof(char) * (1 + nonLen) * (etd->isUTF8 ? 1 : 2));
2160 		if (!etd->NonItemText) return GF_OUT_OF_MEM;
2161 		gf_bs_read_data(bs, etd->NonItemText, nonLen * (etd->isUTF8 ? 1 : 2));
2162 		nbBytes += nonLen * (etd->isUTF8 ? 1 : 2);
2163 	}
2164 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2165 	return GF_OK;
2166 }
2167 
2168 
gf_odf_size_exp_text(GF_ExpandedTextual * etd,u32 * outSize)2169 GF_Err gf_odf_size_exp_text(GF_ExpandedTextual *etd, u32 *outSize)
2170 {
2171 	u32 i, len, nonLen, lentmp, count;
2172 	GF_ETD_ItemText *tmp;
2173 	if (!etd) return GF_BAD_PARAM;
2174 
2175 	*outSize = 5;
2176 	if (gf_list_count(etd->itemDescriptionList) != gf_list_count(etd->itemTextList)) return GF_ODF_INVALID_DESCRIPTOR;
2177 
2178 	count = gf_list_count(etd->itemDescriptionList);
2179 	for (i = 0; i<count; i++) {
2180 		tmp = (GF_ETD_ItemText *)gf_list_get(etd->itemDescriptionList, i);
2181 		*outSize += OD_SizeUTF8String(tmp->text, etd->isUTF8);
2182 		tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, i);
2183 		*outSize += OD_SizeUTF8String(tmp->text, etd->isUTF8);
2184 	}
2185 	*outSize += 1;
2186 	if (etd->NonItemText) {
2187 		if (etd->isUTF8) {
2188 			nonLen = (u32)strlen((const char*)etd->NonItemText);
2189 		}
2190 		else {
2191 			nonLen = (u32)gf_utf8_wcslen((const unsigned short*)etd->NonItemText);
2192 		}
2193 	}
2194 	else {
2195 		nonLen = 0;
2196 	}
2197 	len = 255;
2198 	lentmp = nonLen;
2199 	if (lentmp < 255) {
2200 		len = lentmp;
2201 	}
2202 	while (len == 255) {
2203 		*outSize += 1;
2204 		lentmp -= 255;
2205 		if (lentmp < 255) {
2206 			len = lentmp;
2207 		}
2208 	}
2209 	*outSize += nonLen * (etd->isUTF8 ? 1 : 2);
2210 	return GF_OK;
2211 }
2212 
gf_odf_write_exp_text(GF_BitStream * bs,GF_ExpandedTextual * etd)2213 GF_Err gf_odf_write_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd)
2214 {
2215 	GF_Err e;
2216 	u32 size, i, len, nonLen, lentmp, count;
2217 	GF_ETD_ItemText *tmp;
2218 	if (!etd) return GF_BAD_PARAM;
2219 
2220 	if (gf_list_count(etd->itemDescriptionList) != gf_list_count(etd->itemTextList)) return GF_ODF_INVALID_DESCRIPTOR;
2221 
2222 	e = gf_odf_size_descriptor((GF_Descriptor *)etd, &size);
2223 	if (e) return e;
2224 	e = gf_odf_write_base_descriptor(bs, etd->tag, size);
2225 	if (e) return e;
2226 
2227 	gf_bs_write_int(bs, etd->langCode, 24);
2228 	gf_bs_write_int(bs, etd->isUTF8, 1);
2229 	gf_bs_write_int(bs, 0, 7);		//aligned
2230 	gf_bs_write_int(bs, gf_list_count(etd->itemDescriptionList), 8);
2231 
2232 	count = gf_list_count(etd->itemDescriptionList);
2233 	for (i = 0; i<count; i++) {
2234 		tmp = (GF_ETD_ItemText *)gf_list_get(etd->itemDescriptionList, i);
2235 		OD_WriteUTF8String(bs, tmp->text, etd->isUTF8);
2236 		tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, i);
2237 		OD_WriteUTF8String(bs, tmp->text, etd->isUTF8);
2238 	}
2239 	if (etd->NonItemText) {
2240 		if (etd->isUTF8) {
2241 			nonLen = (u32)strlen((const char*)etd->NonItemText);
2242 		}
2243 		else {
2244 			nonLen = (u32)gf_utf8_wcslen((const unsigned short*)etd->NonItemText);
2245 		}
2246 	}
2247 	else {
2248 		nonLen = 0;
2249 	}
2250 	lentmp = nonLen;
2251 	len = lentmp < 255 ? lentmp : 255;
2252 	while (len == 255) {
2253 		gf_bs_write_int(bs, len, 8);
2254 		lentmp -= len;
2255 		len = lentmp < 255 ? lentmp : 255;
2256 	}
2257 	gf_bs_write_int(bs, len, 8);
2258 	gf_bs_write_data(bs, etd->NonItemText, nonLen * (etd->isUTF8 ? 1 : 2));
2259 	return GF_OK;
2260 }
2261 
gf_odf_new_pl_ext()2262 GF_Descriptor *gf_odf_new_pl_ext()
2263 {
2264 	GF_PLExt *newDesc = (GF_PLExt *)gf_malloc(sizeof(GF_PLExt));
2265 	if (!newDesc) return NULL;
2266 	newDesc->AudioProfileLevelIndication = 0;
2267 	newDesc->GraphicsProfileLevelIndication = 0;
2268 	newDesc->MPEGJProfileLevelIndication = 0;
2269 	newDesc->ODProfileLevelIndication = 0;
2270 	newDesc->profileLevelIndicationIndex = 0;
2271 	newDesc->SceneProfileLevelIndication = 0;
2272 	newDesc->VisualProfileLevelIndication = 0;
2273 	newDesc->tag = GF_ODF_EXT_PL_TAG;
2274 	return (GF_Descriptor *)newDesc;
2275 }
2276 
gf_odf_del_pl_ext(GF_PLExt * pld)2277 GF_Err gf_odf_del_pl_ext(GF_PLExt *pld)
2278 {
2279 	if (!pld) return GF_BAD_PARAM;
2280 
2281 	gf_free(pld);
2282 	return GF_OK;
2283 }
2284 
gf_odf_read_pl_ext(GF_BitStream * bs,GF_PLExt * pld,u32 DescSize)2285 GF_Err gf_odf_read_pl_ext(GF_BitStream *bs, GF_PLExt *pld, u32 DescSize)
2286 {
2287 	u32 nbBytes = 0;
2288 	if (!pld) return GF_BAD_PARAM;
2289 
2290 	pld->profileLevelIndicationIndex = gf_bs_read_int(bs, 8);
2291 	pld->ODProfileLevelIndication = gf_bs_read_int(bs, 8);
2292 	pld->SceneProfileLevelIndication = gf_bs_read_int(bs, 8);
2293 	pld->AudioProfileLevelIndication = gf_bs_read_int(bs, 8);
2294 	pld->VisualProfileLevelIndication = gf_bs_read_int(bs, 8);
2295 	pld->GraphicsProfileLevelIndication = gf_bs_read_int(bs, 8);
2296 	pld->MPEGJProfileLevelIndication = gf_bs_read_int(bs, 8);
2297 
2298 	nbBytes += 7;
2299 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2300 	return GF_OK;
2301 }
2302 
gf_odf_size_pl_ext(GF_PLExt * pld,u32 * outSize)2303 GF_Err gf_odf_size_pl_ext(GF_PLExt *pld, u32 *outSize)
2304 {
2305 	if (!pld) return GF_BAD_PARAM;
2306 
2307 	*outSize = 7;
2308 	return GF_OK;
2309 }
2310 
gf_odf_write_pl_ext(GF_BitStream * bs,GF_PLExt * pld)2311 GF_Err gf_odf_write_pl_ext(GF_BitStream *bs, GF_PLExt *pld)
2312 {
2313 	GF_Err e;
2314 	u32 size;
2315 	if (!pld) return GF_BAD_PARAM;
2316 
2317 	e = gf_odf_size_descriptor((GF_Descriptor *)pld, &size);
2318 	if (e) return e;
2319 	e = gf_odf_write_base_descriptor(bs, pld->tag, size);
2320 	if (e) return e;
2321 
2322 	gf_bs_write_int(bs, pld->profileLevelIndicationIndex, 8);
2323 	gf_bs_write_int(bs, pld->ODProfileLevelIndication, 8);
2324 	gf_bs_write_int(bs, pld->SceneProfileLevelIndication, 8);
2325 	gf_bs_write_int(bs, pld->AudioProfileLevelIndication, 8);
2326 	gf_bs_write_int(bs, pld->VisualProfileLevelIndication, 8);
2327 	gf_bs_write_int(bs, pld->GraphicsProfileLevelIndication, 8);
2328 	gf_bs_write_int(bs, pld->MPEGJProfileLevelIndication, 8);
2329 	return GF_OK;
2330 }
2331 
gf_odf_new_ipi_ptr()2332 GF_Descriptor *gf_odf_new_ipi_ptr()
2333 {
2334 	GF_IPIPtr *newDesc = (GF_IPIPtr *)gf_malloc(sizeof(GF_IPIPtr));
2335 	if (!newDesc) return NULL;
2336 	newDesc->IPI_ES_Id = 0;
2337 	newDesc->tag = GF_ODF_IPI_PTR_TAG;
2338 	return (GF_Descriptor *)newDesc;
2339 }
2340 
gf_odf_del_ipi_ptr(GF_IPIPtr * ipid)2341 GF_Err gf_odf_del_ipi_ptr(GF_IPIPtr *ipid)
2342 {
2343 	if (!ipid) return GF_BAD_PARAM;
2344 	gf_free(ipid);
2345 	return GF_OK;
2346 }
2347 
gf_odf_read_ipi_ptr(GF_BitStream * bs,GF_IPIPtr * ipid,u32 DescSize)2348 GF_Err gf_odf_read_ipi_ptr(GF_BitStream *bs, GF_IPIPtr *ipid, u32 DescSize)
2349 {
2350 	u32 nbBytes = 0;
2351 	if (!ipid) return GF_BAD_PARAM;
2352 
2353 	ipid->IPI_ES_Id = gf_bs_read_int(bs, 16);
2354 	nbBytes += 2;
2355 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2356 	return GF_OK;
2357 }
2358 
gf_odf_size_ipi_ptr(GF_IPIPtr * ipid,u32 * outSize)2359 GF_Err gf_odf_size_ipi_ptr(GF_IPIPtr *ipid, u32 *outSize)
2360 {
2361 	if (!ipid) return GF_BAD_PARAM;
2362 	*outSize = 2;
2363 	return GF_OK;
2364 }
2365 
gf_odf_write_ipi_ptr(GF_BitStream * bs,GF_IPIPtr * ipid)2366 GF_Err gf_odf_write_ipi_ptr(GF_BitStream *bs, GF_IPIPtr *ipid)
2367 {
2368 	GF_Err e;
2369 	u32 size;
2370 	if (!ipid) return GF_BAD_PARAM;
2371 	e = gf_odf_size_descriptor((GF_Descriptor *)ipid, &size);
2372 	if (e) return e;
2373 	e = gf_odf_write_base_descriptor(bs, ipid->tag, size);
2374 	if (e) return e;
2375 	gf_bs_write_int(bs, ipid->IPI_ES_Id, 16);
2376 	return GF_OK;
2377 }
2378 
gf_odf_new_ipmp()2379 GF_Descriptor *gf_odf_new_ipmp()
2380 {
2381 	GF_IPMP_Descriptor *newDesc;
2382 	GF_SAFEALLOC(newDesc, GF_IPMP_Descriptor);
2383 	if (!newDesc) return NULL;
2384 
2385 	newDesc->ipmpx_data = gf_list_new();
2386 	newDesc->tag = GF_ODF_IPMP_TAG;
2387 	return (GF_Descriptor *)newDesc;
2388 }
gf_odf_del_ipmp(GF_IPMP_Descriptor * ipmp)2389 GF_Err gf_odf_del_ipmp(GF_IPMP_Descriptor *ipmp)
2390 {
2391 	if (!ipmp) return GF_BAD_PARAM;
2392 	if (ipmp->opaque_data) gf_free(ipmp->opaque_data);
2393 #ifndef GPAC_MINIMAL_ODF
2394 	/*TODO DELETE IPMPX*/
2395 	while (gf_list_count(ipmp->ipmpx_data)) {
2396 		GF_IPMPX_Data *p = (GF_IPMPX_Data *)gf_list_get(ipmp->ipmpx_data, 0);
2397 		gf_list_rem(ipmp->ipmpx_data, 0);
2398 		gf_ipmpx_data_del(p);
2399 	}
2400 #endif
2401 	gf_list_del(ipmp->ipmpx_data);
2402 	gf_free(ipmp);
2403 	return GF_OK;
2404 }
2405 
gf_odf_read_ipmp(GF_BitStream * bs,GF_IPMP_Descriptor * ipmp,u32 DescSize)2406 GF_Err gf_odf_read_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp, u32 DescSize)
2407 {
2408 	u32 size;
2409 	u64 nbBytes = 0;
2410 	if (!ipmp) return GF_BAD_PARAM;
2411 
2412 	ipmp->IPMP_DescriptorID = gf_bs_read_int(bs, 8);
2413 	ipmp->IPMPS_Type = gf_bs_read_int(bs, 16);
2414 	nbBytes += 3;
2415 	size = DescSize - 3;
2416 
2417 	/*IPMPX escape*/
2418 	if ((ipmp->IPMP_DescriptorID == 0xFF) && (ipmp->IPMPS_Type == 0xFFFF)) {
2419 		ipmp->IPMP_DescriptorIDEx = gf_bs_read_int(bs, 16);
2420 		gf_bs_read_data(bs, (char*)ipmp->IPMP_ToolID, 16);
2421 		ipmp->control_point = gf_bs_read_int(bs, 8);
2422 		nbBytes += 19;
2423 		if (ipmp->control_point) {
2424 			ipmp->cp_sequence_code = gf_bs_read_int(bs, 8);
2425 			nbBytes += 1;
2426 		}
2427 		while (nbBytes<DescSize) {
2428 			u64 pos;
2429 			GF_Err e;
2430 			GF_IPMPX_Data *p;
2431 			pos = gf_bs_get_position(bs);
2432 			e = gf_ipmpx_data_parse(bs, &p);
2433 			if (e) return e;
2434 			gf_list_add(ipmp->ipmpx_data, p);
2435 			nbBytes += gf_bs_get_position(bs) - pos;
2436 		}
2437 	}
2438 	/*URL*/
2439 	else if (!ipmp->IPMPS_Type) {
2440 		ipmp->opaque_data = (char*)gf_malloc(size + 1);
2441 		if (!ipmp->opaque_data) return GF_OUT_OF_MEM;
2442 		gf_bs_read_data(bs, ipmp->opaque_data, size);
2443 		nbBytes += size;
2444 		ipmp->opaque_data[size] = 0;
2445 		ipmp->opaque_data_size = size;
2446 
2447 	}
2448 	/*data*/
2449 	else {
2450 		ipmp->opaque_data_size = size;
2451 		ipmp->opaque_data = (char*)gf_malloc(size);
2452 		if (!ipmp->opaque_data) return GF_OUT_OF_MEM;
2453 		gf_bs_read_data(bs, ipmp->opaque_data, size);
2454 		nbBytes += size;
2455 	}
2456 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2457 	return GF_OK;
2458 }
2459 
gf_odf_size_ipmp(GF_IPMP_Descriptor * ipmp,u32 * outSize)2460 GF_Err gf_odf_size_ipmp(GF_IPMP_Descriptor *ipmp, u32 *outSize)
2461 {
2462 	u32 i, s;
2463 	if (!ipmp) return GF_BAD_PARAM;
2464 
2465 	*outSize = 3;
2466 	/*IPMPX escape*/
2467 	if ((ipmp->IPMP_DescriptorID == 0xFF) && (ipmp->IPMPS_Type == 0xFFFF)) {
2468 		GF_IPMPX_Data *p;
2469 		*outSize += 19;
2470 		if (ipmp->control_point) *outSize += 1;
2471 		s = 0;
2472 		i = 0;
2473 		while ((p = (GF_IPMPX_Data *)gf_list_enum(ipmp->ipmpx_data, &i))) {
2474 			s += gf_ipmpx_data_full_size(p);
2475 		}
2476 		(*outSize) += s;
2477 	}
2478 	else if (!ipmp->IPMPS_Type) {
2479 		if (!ipmp->opaque_data) return GF_ODF_INVALID_DESCRIPTOR;
2480 		*outSize += (u32)strlen(ipmp->opaque_data);
2481 	}
2482 	else {
2483 		*outSize += ipmp->opaque_data_size;
2484 	}
2485 	return GF_OK;
2486 }
2487 
gf_odf_write_ipmp(GF_BitStream * bs,GF_IPMP_Descriptor * ipmp)2488 GF_Err gf_odf_write_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp)
2489 {
2490 	GF_Err e;
2491 	u32 size, i;
2492 	if (!ipmp) return GF_BAD_PARAM;
2493 
2494 	e = gf_odf_size_descriptor((GF_Descriptor *)ipmp, &size);
2495 	if (e) return e;
2496 	e = gf_odf_write_base_descriptor(bs, ipmp->tag, size);
2497 	if (e) return e;
2498 	gf_bs_write_int(bs, ipmp->IPMP_DescriptorID, 8);
2499 	gf_bs_write_int(bs, ipmp->IPMPS_Type, 16);
2500 
2501 	if ((ipmp->IPMP_DescriptorID == 0xFF) && (ipmp->IPMPS_Type == 0xFFFF)) {
2502 		GF_IPMPX_Data *p;
2503 		gf_bs_write_int(bs, ipmp->IPMP_DescriptorIDEx, 16);
2504 		gf_bs_write_data(bs, (char*)ipmp->IPMP_ToolID, 16);
2505 		gf_bs_write_int(bs, ipmp->control_point, 8);
2506 		if (ipmp->control_point) gf_bs_write_int(bs, ipmp->cp_sequence_code, 8);
2507 
2508 		i = 0;
2509 		while ((p = (GF_IPMPX_Data *)gf_list_enum(ipmp->ipmpx_data, &i))) {
2510 			gf_ipmpx_data_write(bs, p);
2511 		}
2512 	}
2513 	else if (!ipmp->IPMPS_Type) {
2514 		if (!ipmp->opaque_data) return GF_ODF_INVALID_DESCRIPTOR;
2515 		gf_bs_write_data(bs, ipmp->opaque_data, (u32)strlen(ipmp->opaque_data));
2516 	}
2517 	else {
2518 		gf_bs_write_data(bs, ipmp->opaque_data, ipmp->opaque_data_size);
2519 	}
2520 	return GF_OK;
2521 }
2522 
gf_odf_new_ipmp_ptr()2523 GF_Descriptor *gf_odf_new_ipmp_ptr()
2524 {
2525 	GF_IPMPPtr *newDesc;
2526 	GF_SAFEALLOC(newDesc, GF_IPMPPtr);
2527 	if (!newDesc) return NULL;
2528 	newDesc->tag = GF_ODF_IPMP_PTR_TAG;
2529 	return (GF_Descriptor *)newDesc;
2530 }
gf_odf_del_ipmp_ptr(GF_IPMPPtr * ipmpd)2531 GF_Err gf_odf_del_ipmp_ptr(GF_IPMPPtr *ipmpd)
2532 {
2533 	if (!ipmpd) return GF_BAD_PARAM;
2534 	gf_free(ipmpd);
2535 	return GF_OK;
2536 }
2537 
gf_odf_read_ipmp_ptr(GF_BitStream * bs,GF_IPMPPtr * ipmpd,u32 DescSize)2538 GF_Err gf_odf_read_ipmp_ptr(GF_BitStream *bs, GF_IPMPPtr *ipmpd, u32 DescSize)
2539 {
2540 	u32 nbBytes = 0;
2541 	if (!ipmpd) return GF_BAD_PARAM;
2542 	ipmpd->IPMP_DescriptorID = gf_bs_read_int(bs, 8);
2543 	nbBytes += 1;
2544 	if (ipmpd->IPMP_DescriptorID == 0xFF) {
2545 		ipmpd->IPMP_DescriptorIDEx = gf_bs_read_int(bs, 16);
2546 		ipmpd->IPMP_ES_ID = gf_bs_read_int(bs, 16);
2547 		nbBytes += 4;
2548 	}
2549 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2550 	return GF_OK;
2551 }
gf_odf_size_ipmp_ptr(GF_IPMPPtr * ipmpd,u32 * outSize)2552 GF_Err gf_odf_size_ipmp_ptr(GF_IPMPPtr *ipmpd, u32 *outSize)
2553 {
2554 	if (!ipmpd) return GF_BAD_PARAM;
2555 	*outSize = 1;
2556 	if (ipmpd->IPMP_DescriptorID == 0xFF) *outSize += 4;
2557 	return GF_OK;
2558 }
gf_odf_write_ipmp_ptr(GF_BitStream * bs,GF_IPMPPtr * ipmpd)2559 GF_Err gf_odf_write_ipmp_ptr(GF_BitStream *bs, GF_IPMPPtr *ipmpd)
2560 {
2561 	GF_Err e;
2562 	u32 size;
2563 	if (!ipmpd) return GF_BAD_PARAM;
2564 
2565 	e = gf_odf_size_descriptor((GF_Descriptor *)ipmpd, &size);
2566 	if (e) return e;
2567 	e = gf_odf_write_base_descriptor(bs, ipmpd->tag, size);
2568 	if (e) return e;
2569 	gf_bs_write_int(bs, ipmpd->IPMP_DescriptorID, 8);
2570 	if (ipmpd->IPMP_DescriptorID == 0xFF) {
2571 		gf_bs_write_int(bs, ipmpd->IPMP_DescriptorIDEx, 16);
2572 		gf_bs_write_int(bs, ipmpd->IPMP_ES_ID, 16);
2573 	}
2574 	return GF_OK;
2575 }
2576 
gf_odf_new_kw()2577 GF_Descriptor *gf_odf_new_kw()
2578 {
2579 	GF_KeyWord *newDesc = (GF_KeyWord *)gf_malloc(sizeof(GF_KeyWord));
2580 	if (!newDesc) return NULL;
2581 
2582 	newDesc->keyWordsList = gf_list_new();
2583 	if (!newDesc->keyWordsList) {
2584 		gf_free(newDesc);
2585 		return NULL;
2586 	}
2587 	newDesc->isUTF8 = 0;
2588 	newDesc->languageCode = 0;
2589 	newDesc->tag = GF_ODF_KW_TAG;
2590 	return (GF_Descriptor *)newDesc;
2591 }
2592 
gf_odf_del_kw(GF_KeyWord * kwd)2593 GF_Err gf_odf_del_kw(GF_KeyWord *kwd)
2594 {
2595 	if (!kwd) return GF_BAD_PARAM;
2596 
2597 	while (gf_list_count(kwd->keyWordsList)) {
2598 		GF_KeyWordItem *tmp = (GF_KeyWordItem*)gf_list_get(kwd->keyWordsList, 0);
2599 		if (tmp) {
2600 			if (tmp->keyWord) gf_free(tmp->keyWord);
2601 			gf_free(tmp);
2602 		}
2603 	}
2604 	gf_list_del(kwd->keyWordsList);
2605 	gf_free(kwd);
2606 	return GF_OK;
2607 }
2608 
gf_odf_read_kw(GF_BitStream * bs,GF_KeyWord * kwd,u32 DescSize)2609 GF_Err gf_odf_read_kw(GF_BitStream *bs, GF_KeyWord *kwd, u32 DescSize)
2610 {
2611 	GF_Err e;
2612 	u32 nbBytes = 0, i, kwcount, len;
2613 	if (!kwd) return GF_BAD_PARAM;
2614 
2615 	kwd->languageCode = gf_bs_read_int(bs, 24);
2616 	kwd->isUTF8 = gf_bs_read_int(bs, 1);
2617 	/*aligned = */gf_bs_read_int(bs, 7);
2618 	kwcount = gf_bs_read_int(bs, 8);
2619 	nbBytes += 5;
2620 
2621 	for (i = 0; i < kwcount; i++) {
2622 		GF_KeyWordItem *tmp = (GF_KeyWordItem*)gf_malloc(sizeof(GF_KeyWordItem));
2623 		if (!tmp) return GF_OUT_OF_MEM;
2624 		e = OD_ReadUTF8String(bs, &tmp->keyWord, kwd->isUTF8, &len);
2625 		if (e) return e;
2626 		e = gf_list_add(kwd->keyWordsList, tmp);
2627 		if (e) return e;
2628 		nbBytes += len;
2629 	}
2630 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2631 	return GF_OK;
2632 }
2633 
2634 
gf_odf_size_kw(GF_KeyWord * kwd,u32 * outSize)2635 GF_Err gf_odf_size_kw(GF_KeyWord *kwd, u32 *outSize)
2636 {
2637 	u32 i;
2638 	GF_KeyWordItem *tmp;
2639 	if (!kwd) return GF_BAD_PARAM;
2640 
2641 	*outSize = 5;
2642 	i = 0;
2643 	while ((tmp = (GF_KeyWordItem *)gf_list_enum(kwd->keyWordsList, &i))) {
2644 		*outSize += OD_SizeUTF8String(tmp->keyWord, kwd->isUTF8);
2645 	}
2646 	return GF_OK;
2647 }
gf_odf_write_kw(GF_BitStream * bs,GF_KeyWord * kwd)2648 GF_Err gf_odf_write_kw(GF_BitStream *bs, GF_KeyWord *kwd)
2649 {
2650 	GF_Err e;
2651 	u32 size, i;
2652 	GF_KeyWordItem *tmp;
2653 	if (!kwd) return GF_BAD_PARAM;
2654 
2655 	e = gf_odf_size_descriptor((GF_Descriptor *)kwd, &size);
2656 	if (e) return e;
2657 	e = gf_odf_write_base_descriptor(bs, kwd->tag, size);
2658 	if (e) return e;
2659 
2660 	gf_bs_write_int(bs, kwd->languageCode, 24);
2661 	gf_bs_write_int(bs, kwd->isUTF8, 1);
2662 	gf_bs_write_int(bs, 0, 7);		//aligned(8)
2663 	gf_bs_write_int(bs, gf_list_count(kwd->keyWordsList), 8);
2664 
2665 	i = 0;
2666 	while ((tmp = (GF_KeyWordItem *)gf_list_enum(kwd->keyWordsList, &i))) {
2667 		OD_WriteUTF8String(bs, tmp->keyWord, kwd->isUTF8);
2668 	}
2669 	return GF_OK;
2670 }
2671 
gf_odf_new_oci_date()2672 GF_Descriptor *gf_odf_new_oci_date()
2673 {
2674 	GF_OCI_Data *newDesc = (GF_OCI_Data *)gf_malloc(sizeof(GF_OCI_Data));
2675 	if (!newDesc) return NULL;
2676 	memset(newDesc->OCICreationDate, 0, 5);
2677 	newDesc->tag = GF_ODF_OCI_DATE_TAG;
2678 	return (GF_Descriptor *)newDesc;
2679 }
2680 
gf_odf_del_oci_date(GF_OCI_Data * ocd)2681 GF_Err gf_odf_del_oci_date(GF_OCI_Data *ocd)
2682 {
2683 	if (!ocd) return GF_BAD_PARAM;
2684 	gf_free(ocd);
2685 	return GF_OK;
2686 }
2687 
gf_odf_read_oci_date(GF_BitStream * bs,GF_OCI_Data * ocd,u32 DescSize)2688 GF_Err gf_odf_read_oci_date(GF_BitStream *bs, GF_OCI_Data *ocd, u32 DescSize)
2689 {
2690 	u32 nbBytes = 0;
2691 	if (!ocd) return GF_BAD_PARAM;
2692 
2693 	gf_bs_read_data(bs, ocd->OCICreationDate, DATE_CODING_BIT_LEN);
2694 	nbBytes += DATE_CODING_BIT_LEN / 8;
2695 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2696 	return GF_OK;
2697 }
2698 
gf_odf_size_oci_date(GF_OCI_Data * ocd,u32 * outSize)2699 GF_Err gf_odf_size_oci_date(GF_OCI_Data *ocd, u32 *outSize)
2700 {
2701 	if (!ocd) return GF_BAD_PARAM;
2702 	*outSize = (DATE_CODING_BIT_LEN / 8);
2703 	return GF_OK;
2704 }
2705 
gf_odf_write_oci_date(GF_BitStream * bs,GF_OCI_Data * ocd)2706 GF_Err gf_odf_write_oci_date(GF_BitStream *bs, GF_OCI_Data *ocd)
2707 {
2708 	GF_Err e;
2709 	u32 size;
2710 	if (!ocd) return GF_BAD_PARAM;
2711 
2712 	e = gf_odf_size_descriptor((GF_Descriptor *)ocd, &size);
2713 	if (e) return e;
2714 	e = gf_odf_write_base_descriptor(bs, ocd->tag, size);
2715 	if (e) return e;
2716 	gf_bs_write_data(bs, ocd->OCICreationDate, DATE_CODING_BIT_LEN);
2717 	return GF_OK;
2718 }
2719 
gf_odf_new_oci_name()2720 GF_Descriptor *gf_odf_new_oci_name()
2721 {
2722 	GF_OCICreators *newDesc = (GF_OCICreators *)gf_malloc(sizeof(GF_OCICreators));
2723 	if (!newDesc) return NULL;
2724 
2725 	newDesc->OCICreators = gf_list_new();
2726 	if (!newDesc->OCICreators) {
2727 		gf_free(newDesc);
2728 		return NULL;
2729 	}
2730 	newDesc->tag = GF_ODF_OCI_NAME_TAG;
2731 	return (GF_Descriptor *)newDesc;
2732 }
gf_odf_del_oci_name(GF_OCICreators * ocn)2733 GF_Err gf_odf_del_oci_name(GF_OCICreators *ocn)
2734 {
2735 	u32 i;
2736 	GF_OCICreator_item *tmp;
2737 	if (!ocn) return GF_BAD_PARAM;
2738 
2739 	i = 0;
2740 	while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
2741 		if (tmp->OCICreatorName) gf_free(tmp->OCICreatorName);
2742 		gf_free(tmp);
2743 	}
2744 	gf_list_del(ocn->OCICreators);
2745 	gf_free(ocn);
2746 	return GF_OK;
2747 }
2748 
gf_odf_read_oci_name(GF_BitStream * bs,GF_OCICreators * ocn,u32 DescSize)2749 GF_Err gf_odf_read_oci_name(GF_BitStream *bs, GF_OCICreators *ocn, u32 DescSize)
2750 {
2751 	GF_Err e;
2752 	u32 nbBytes = 0;
2753 	u32 i, count, len;
2754 	if (!ocn) return GF_BAD_PARAM;
2755 
2756 	count = gf_bs_read_int(bs, 8);
2757 	nbBytes += 1;
2758 	for (i = 0; i< count; i++) {
2759 		GF_OCICreator_item *tmp = (GF_OCICreator_item*)gf_malloc(sizeof(GF_OCICreator_item));
2760 		if (!tmp) return GF_OUT_OF_MEM;
2761 		tmp->langCode = gf_bs_read_int(bs, 24);
2762 		tmp->isUTF8 = gf_bs_read_int(bs, 1);
2763 		/*aligned = */gf_bs_read_int(bs, 7);
2764 		nbBytes += 4;
2765 		e = OD_ReadUTF8String(bs, &tmp->OCICreatorName, tmp->isUTF8, &len);
2766 		if (e) return e;
2767 		nbBytes += len;
2768 		e = gf_list_add(ocn->OCICreators, tmp);
2769 		if (e) return e;
2770 	}
2771 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2772 	return GF_OK;
2773 }
2774 
gf_odf_size_oci_name(GF_OCICreators * ocn,u32 * outSize)2775 GF_Err gf_odf_size_oci_name(GF_OCICreators *ocn, u32 *outSize)
2776 {
2777 	u32 i;
2778 	GF_OCICreator_item *tmp;
2779 	if (!ocn) return GF_BAD_PARAM;
2780 
2781 	*outSize = 1;
2782 	i = 0;
2783 	while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
2784 		*outSize += 4 + OD_SizeUTF8String(tmp->OCICreatorName, tmp->isUTF8);
2785 	}
2786 	return GF_OK;
2787 }
2788 
gf_odf_write_oci_name(GF_BitStream * bs,GF_OCICreators * ocn)2789 GF_Err gf_odf_write_oci_name(GF_BitStream *bs, GF_OCICreators *ocn)
2790 {
2791 	GF_Err e;
2792 	u32 size;
2793 	u32 i;
2794 	GF_OCICreator_item *tmp;
2795 	if (!ocn) return GF_BAD_PARAM;
2796 
2797 	e = gf_odf_size_descriptor((GF_Descriptor *)ocn, &size);
2798 	if (e) return e;
2799 	e = gf_odf_write_base_descriptor(bs, ocn->tag, size);
2800 	if (e) return e;
2801 	gf_bs_write_int(bs, gf_list_count(ocn->OCICreators), 8);
2802 
2803 	i = 0;
2804 	while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
2805 		gf_bs_write_int(bs, tmp->langCode, 24);
2806 		gf_bs_write_int(bs, tmp->isUTF8, 1);
2807 		gf_bs_write_int(bs, 0, 7);		//aligned
2808 		gf_bs_write_int(bs, (u32)strlen(tmp->OCICreatorName), 8);
2809 		OD_WriteUTF8String(bs, tmp->OCICreatorName, tmp->isUTF8);
2810 	}
2811 	return GF_OK;
2812 }
2813 
2814 
gf_odf_new_pl_idx()2815 GF_Descriptor *gf_odf_new_pl_idx()
2816 {
2817 	GF_PL_IDX *newDesc = (GF_PL_IDX *)gf_malloc(sizeof(GF_PL_IDX));
2818 	if (!newDesc) return NULL;
2819 	newDesc->profileLevelIndicationIndex = 0;
2820 	newDesc->tag = GF_ODF_PL_IDX_TAG;
2821 	return (GF_Descriptor *)newDesc;
2822 }
2823 
gf_odf_del_pl_idx(GF_PL_IDX * plid)2824 GF_Err gf_odf_del_pl_idx(GF_PL_IDX *plid)
2825 {
2826 	if (!plid) return GF_BAD_PARAM;
2827 	gf_free(plid);
2828 	return GF_OK;
2829 }
2830 
gf_odf_read_pl_idx(GF_BitStream * bs,GF_PL_IDX * plid,u32 DescSize)2831 GF_Err gf_odf_read_pl_idx(GF_BitStream *bs, GF_PL_IDX *plid, u32 DescSize)
2832 {
2833 	u32 nbBytes = 0;
2834 	if (!plid) return GF_BAD_PARAM;
2835 
2836 	plid->profileLevelIndicationIndex = gf_bs_read_int(bs, 8);
2837 	nbBytes += 1;
2838 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2839 	return GF_OK;
2840 }
gf_odf_size_pl_idx(GF_PL_IDX * plid,u32 * outSize)2841 GF_Err gf_odf_size_pl_idx(GF_PL_IDX *plid, u32 *outSize)
2842 {
2843 	if (!plid) return GF_BAD_PARAM;
2844 	*outSize = 1;
2845 	return GF_OK;
2846 }
gf_odf_write_pl_idx(GF_BitStream * bs,GF_PL_IDX * plid)2847 GF_Err gf_odf_write_pl_idx(GF_BitStream *bs, GF_PL_IDX *plid)
2848 {
2849 	GF_Err e;
2850 	u32 size;
2851 	if (!plid) return GF_BAD_PARAM;
2852 	e = gf_odf_size_descriptor((GF_Descriptor *)plid, &size);
2853 	if (e) return e;
2854 	e = gf_odf_write_base_descriptor(bs, plid->tag, size);
2855 	if (e) return e;
2856 	gf_bs_write_int(bs, plid->profileLevelIndicationIndex, 8);
2857 	return GF_OK;
2858 }
2859 
2860 
gf_odf_new_rating()2861 GF_Descriptor *gf_odf_new_rating()
2862 {
2863 	GF_Rating *newDesc = (GF_Rating *)gf_malloc(sizeof(GF_Rating));
2864 	if (!newDesc) return NULL;
2865 
2866 	newDesc->infoLength = 0;
2867 	newDesc->ratingInfo = NULL;
2868 	newDesc->ratingCriteria = 0;
2869 	newDesc->ratingEntity = 0;
2870 	newDesc->tag = GF_ODF_RATING_TAG;
2871 	return (GF_Descriptor *)newDesc;
2872 }
2873 
gf_odf_del_rating(GF_Rating * rd)2874 GF_Err gf_odf_del_rating(GF_Rating *rd)
2875 {
2876 	if (!rd) return GF_BAD_PARAM;
2877 
2878 	if (rd->ratingInfo) gf_free(rd->ratingInfo);
2879 	gf_free(rd);
2880 	return GF_OK;
2881 }
2882 
gf_odf_read_rating(GF_BitStream * bs,GF_Rating * rd,u32 DescSize)2883 GF_Err gf_odf_read_rating(GF_BitStream *bs, GF_Rating *rd, u32 DescSize)
2884 {
2885 	u32 nbBytes = 0;
2886 	if (!rd) return GF_BAD_PARAM;
2887 
2888 	rd->ratingEntity = gf_bs_read_int(bs, 32);
2889 	rd->ratingCriteria = gf_bs_read_int(bs, 16);
2890 	rd->infoLength = DescSize - 6;
2891 	nbBytes += 6;
2892 
2893 	rd->ratingInfo = (char*)gf_malloc(rd->infoLength);
2894 	if (!rd->ratingInfo) return GF_OUT_OF_MEM;
2895 	gf_bs_read_data(bs, rd->ratingInfo, rd->infoLength);
2896 	nbBytes += rd->infoLength;
2897 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2898 	return GF_OK;
2899 }
2900 
gf_odf_size_rating(GF_Rating * rd,u32 * outSize)2901 GF_Err gf_odf_size_rating(GF_Rating *rd, u32 *outSize)
2902 {
2903 	if (!rd) return GF_BAD_PARAM;
2904 
2905 	*outSize = 6 + rd->infoLength;
2906 	return GF_OK;
2907 }
2908 
gf_odf_write_rating(GF_BitStream * bs,GF_Rating * rd)2909 GF_Err gf_odf_write_rating(GF_BitStream *bs, GF_Rating *rd)
2910 {
2911 	GF_Err e;
2912 	u32 size;
2913 	if (!rd) return GF_BAD_PARAM;
2914 	e = gf_odf_size_descriptor((GF_Descriptor *)rd, &size);
2915 	if (e) return e;
2916 	e = gf_odf_write_base_descriptor(bs, rd->tag, size);
2917 	if (e) return e;
2918 	gf_bs_write_int(bs, rd->ratingEntity, 32);
2919 	gf_bs_write_int(bs, rd->ratingCriteria, 16);
2920 	gf_bs_write_data(bs, rd->ratingInfo, rd->infoLength);
2921 	return GF_OK;
2922 }
2923 
2924 
gf_odf_new_reg()2925 GF_Descriptor *gf_odf_new_reg()
2926 {
2927 	GF_Registration *newDesc = (GF_Registration *)gf_malloc(sizeof(GF_Registration));
2928 	if (!newDesc) return NULL;
2929 	newDesc->additionalIdentificationInfo = NULL;
2930 	newDesc->dataLength = 0;
2931 	newDesc->formatIdentifier = 0;
2932 	newDesc->tag = GF_ODF_REG_TAG;
2933 	return (GF_Descriptor *)newDesc;
2934 }
2935 
gf_odf_del_reg(GF_Registration * reg)2936 GF_Err gf_odf_del_reg(GF_Registration *reg)
2937 {
2938 	if (!reg) return GF_BAD_PARAM;
2939 
2940 	if (reg->additionalIdentificationInfo) gf_free(reg->additionalIdentificationInfo);
2941 	gf_free(reg);
2942 	return GF_OK;
2943 }
2944 
gf_odf_read_reg(GF_BitStream * bs,GF_Registration * reg,u32 DescSize)2945 GF_Err gf_odf_read_reg(GF_BitStream *bs, GF_Registration *reg, u32 DescSize)
2946 {
2947 	u32 nbBytes = 0;
2948 	if (!reg) return GF_BAD_PARAM;
2949 
2950 	reg->formatIdentifier = gf_bs_read_int(bs, 32);
2951 	reg->dataLength = DescSize - 4;
2952 	reg->additionalIdentificationInfo = (char*)gf_malloc(reg->dataLength);
2953 	if (!reg->additionalIdentificationInfo) return GF_OUT_OF_MEM;
2954 	gf_bs_read_data(bs, reg->additionalIdentificationInfo, reg->dataLength);
2955 	nbBytes += reg->dataLength + 4;
2956 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
2957 	return GF_OK;
2958 }
2959 
2960 
gf_odf_size_reg(GF_Registration * reg,u32 * outSize)2961 GF_Err gf_odf_size_reg(GF_Registration *reg, u32 *outSize)
2962 {
2963 	if (!reg) return GF_BAD_PARAM;
2964 
2965 	*outSize = 4 + reg->dataLength;
2966 	return GF_OK;
2967 }
2968 
gf_odf_write_reg(GF_BitStream * bs,GF_Registration * reg)2969 GF_Err gf_odf_write_reg(GF_BitStream *bs, GF_Registration *reg)
2970 {
2971 	GF_Err e;
2972 	u32 size;
2973 	if (!reg) return GF_BAD_PARAM;
2974 
2975 	e = gf_odf_size_descriptor((GF_Descriptor *)reg, &size);
2976 	if (e) return e;
2977 	e = gf_odf_write_base_descriptor(bs, reg->tag, size);
2978 	if (e) return e;
2979 
2980 	gf_bs_write_int(bs, reg->formatIdentifier, 32);
2981 	gf_bs_write_data(bs, reg->additionalIdentificationInfo, reg->dataLength);
2982 	return GF_OK;
2983 }
2984 
gf_odf_new_short_text()2985 GF_Descriptor *gf_odf_new_short_text()
2986 {
2987 	GF_ShortTextual *newDesc = (GF_ShortTextual *)gf_malloc(sizeof(GF_ShortTextual));
2988 	if (!newDesc) return NULL;
2989 
2990 	newDesc->eventName = NULL;
2991 	newDesc->eventText = NULL;
2992 	newDesc->isUTF8 = 0;
2993 	newDesc->langCode = 0;
2994 	newDesc->tag = GF_ODF_SHORT_TEXT_TAG;
2995 	return (GF_Descriptor *)newDesc;
2996 }
2997 
gf_odf_del_short_text(GF_ShortTextual * std)2998 GF_Err gf_odf_del_short_text(GF_ShortTextual *std)
2999 {
3000 	if (!std) return GF_BAD_PARAM;
3001 
3002 	if (std->eventName) gf_free(std->eventName);
3003 	if (std->eventText) gf_free(std->eventText);
3004 	gf_free(std);
3005 	return GF_OK;
3006 }
3007 
gf_odf_read_short_text(GF_BitStream * bs,GF_ShortTextual * std,u32 DescSize)3008 GF_Err gf_odf_read_short_text(GF_BitStream *bs, GF_ShortTextual *std, u32 DescSize)
3009 {
3010 	GF_Err e;
3011 	u32 nbBytes = 0, len;
3012 	if (!std) return GF_BAD_PARAM;
3013 
3014 	std->langCode = gf_bs_read_int(bs, 24);
3015 	std->isUTF8 = gf_bs_read_int(bs, 1);
3016 	/*aligned = */gf_bs_read_int(bs, 7);
3017 	nbBytes += 4;
3018 
3019 	e = OD_ReadUTF8String(bs, &std->eventName, std->isUTF8, &len);
3020 	if (e) return e;
3021 	nbBytes += len;
3022 	e = OD_ReadUTF8String(bs, &std->eventText, std->isUTF8, &len);
3023 	if (e) return e;
3024 	nbBytes += len;
3025 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3026 	return GF_OK;
3027 }
3028 
gf_odf_size_short_text(GF_ShortTextual * std,u32 * outSize)3029 GF_Err gf_odf_size_short_text(GF_ShortTextual *std, u32 *outSize)
3030 {
3031 	if (!std) return GF_BAD_PARAM;
3032 	*outSize = 4;
3033 	*outSize += OD_SizeUTF8String(std->eventName, std->isUTF8) + OD_SizeUTF8String(std->eventText, std->isUTF8);
3034 	return GF_OK;
3035 }
3036 
gf_odf_write_short_text(GF_BitStream * bs,GF_ShortTextual * std)3037 GF_Err gf_odf_write_short_text(GF_BitStream *bs, GF_ShortTextual *std)
3038 {
3039 	GF_Err e;
3040 	u32 size;
3041 	if (!std) return GF_BAD_PARAM;
3042 
3043 	e = gf_odf_size_descriptor((GF_Descriptor *)std, &size);
3044 	if (e) return e;
3045 	e = gf_odf_write_base_descriptor(bs, std->tag, size);
3046 	if (e) return e;
3047 	gf_bs_write_int(bs, std->langCode, 24);
3048 	gf_bs_write_int(bs, std->isUTF8, 1);
3049 	gf_bs_write_int(bs, 0, 7);
3050 	OD_WriteUTF8String(bs, std->eventName, std->isUTF8);
3051 	OD_WriteUTF8String(bs, std->eventText, std->isUTF8);
3052 	return GF_OK;
3053 }
3054 
gf_odf_new_smpte_camera()3055 GF_Descriptor *gf_odf_new_smpte_camera()
3056 {
3057 	GF_SMPTECamera *newDesc = (GF_SMPTECamera *)gf_malloc(sizeof(GF_SMPTECamera));
3058 	if (!newDesc) return NULL;
3059 
3060 	newDesc->ParamList = gf_list_new();
3061 	if (!newDesc->ParamList) {
3062 		gf_free(newDesc);
3063 		return NULL;
3064 	}
3065 	newDesc->cameraID = 0;
3066 	newDesc->tag = GF_ODF_SMPTE_TAG;
3067 	return (GF_Descriptor *)newDesc;
3068 }
3069 
gf_odf_del_smpte_camera(GF_SMPTECamera * cpd)3070 GF_Err gf_odf_del_smpte_camera(GF_SMPTECamera *cpd)
3071 {
3072 	u32 i;
3073 	GF_SmpteParam *tmp;
3074 	if (!cpd) return GF_BAD_PARAM;
3075 
3076 	i = 0;
3077 	while ((tmp = (GF_SmpteParam *)gf_list_enum(cpd->ParamList, &i))) {
3078 		gf_free(tmp);
3079 	}
3080 	gf_list_del(cpd->ParamList);
3081 	gf_free(cpd);
3082 	return GF_OK;
3083 }
gf_odf_read_smpte_camera(GF_BitStream * bs,GF_SMPTECamera * cpd,u32 DescSize)3084 GF_Err gf_odf_read_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd, u32 DescSize)
3085 {
3086 	GF_Err e;
3087 	u32 nbBytes = 0, i, count;
3088 	if (!cpd) return GF_BAD_PARAM;
3089 
3090 	cpd->cameraID = gf_bs_read_int(bs, 8);
3091 	count = gf_bs_read_int(bs, 8);
3092 	nbBytes += 2;
3093 
3094 	for (i = 0; i< count; i++) {
3095 		GF_SmpteParam *tmp = (GF_SmpteParam*)gf_malloc(sizeof(GF_SmpteParam));
3096 		if (!tmp) return GF_OUT_OF_MEM;
3097 		tmp->paramID = gf_bs_read_int(bs, 8);
3098 		tmp->param = gf_bs_read_int(bs, 32);
3099 		nbBytes += 5;
3100 		e = gf_list_add(cpd->ParamList, tmp);
3101 		if (e) return e;
3102 	}
3103 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3104 	return GF_OK;
3105 }
3106 
gf_odf_size_smpte_camera(GF_SMPTECamera * cpd,u32 * outSize)3107 GF_Err gf_odf_size_smpte_camera(GF_SMPTECamera *cpd, u32 *outSize)
3108 {
3109 	if (!cpd) return GF_BAD_PARAM;
3110 	*outSize = 2 + 5 * gf_list_count(cpd->ParamList);
3111 	return GF_OK;
3112 }
3113 
gf_odf_write_smpte_camera(GF_BitStream * bs,GF_SMPTECamera * cpd)3114 GF_Err gf_odf_write_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd)
3115 {
3116 	GF_Err e;
3117 	GF_SmpteParam *tmp;
3118 	u32 size, i;
3119 	if (!cpd) return GF_BAD_PARAM;
3120 
3121 	e = gf_odf_size_descriptor((GF_Descriptor *)cpd, &size);
3122 	if (e) return e;
3123 	e = gf_odf_write_base_descriptor(bs, cpd->tag, size);
3124 	if (e) return e;
3125 	gf_bs_write_int(bs, cpd->cameraID, 8);
3126 	gf_bs_write_int(bs, gf_list_count(cpd->ParamList), 8);
3127 
3128 	i = 0;
3129 	while ((tmp = (GF_SmpteParam *)gf_list_enum(cpd->ParamList, &i))) {
3130 		gf_bs_write_int(bs, tmp->paramID, 8);
3131 		gf_bs_write_int(bs, tmp->param, 32);
3132 	}
3133 	return GF_OK;
3134 }
3135 
gf_odf_new_sup_cid()3136 GF_Descriptor *gf_odf_new_sup_cid()
3137 {
3138 	GF_SCIDesc *newDesc = (GF_SCIDesc *)gf_malloc(sizeof(GF_SCIDesc));
3139 	if (!newDesc) return NULL;
3140 	newDesc->supplContentIdentifierTitle = NULL;
3141 	newDesc->supplContentIdentifierValue = NULL;
3142 	newDesc->languageCode = 0;
3143 	newDesc->tag = GF_ODF_SCI_TAG;
3144 	return (GF_Descriptor *)newDesc;
3145 }
3146 
gf_odf_del_sup_cid(GF_SCIDesc * scid)3147 GF_Err gf_odf_del_sup_cid(GF_SCIDesc *scid)
3148 {
3149 	if (!scid) return GF_BAD_PARAM;
3150 
3151 	if (scid->supplContentIdentifierTitle) gf_free(scid->supplContentIdentifierTitle);
3152 	if (scid->supplContentIdentifierValue) gf_free(scid->supplContentIdentifierValue);
3153 	gf_free(scid);
3154 	return GF_OK;
3155 }
3156 
gf_odf_read_sup_cid(GF_BitStream * bs,GF_SCIDesc * scid,u32 DescSize)3157 GF_Err gf_odf_read_sup_cid(GF_BitStream *bs, GF_SCIDesc *scid, u32 DescSize)
3158 {
3159 	GF_Err e;
3160 	u32 nbBytes = 0, len;
3161 	if (!scid) return GF_BAD_PARAM;
3162 
3163 	scid->languageCode = gf_bs_read_int(bs, 24);
3164 	nbBytes += 3;
3165 	e = OD_ReadUTF8String(bs, &scid->supplContentIdentifierTitle, GF_TRUE, &len);
3166 	if (e) return e;
3167 	nbBytes += len;
3168 	e = OD_ReadUTF8String(bs, &scid->supplContentIdentifierValue, GF_TRUE, &len);
3169 	if (e) return e;
3170 	nbBytes += len;
3171 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3172 	return GF_OK;
3173 }
3174 
3175 
gf_odf_size_sup_cid(GF_SCIDesc * scid,u32 * outSize)3176 GF_Err gf_odf_size_sup_cid(GF_SCIDesc *scid, u32 *outSize)
3177 {
3178 	if (!scid) return GF_BAD_PARAM;
3179 	*outSize = 3 + OD_SizeUTF8String(scid->supplContentIdentifierTitle, GF_TRUE) + OD_SizeUTF8String(scid->supplContentIdentifierValue, GF_TRUE);
3180 	return GF_OK;
3181 }
gf_odf_write_sup_cid(GF_BitStream * bs,GF_SCIDesc * scid)3182 GF_Err gf_odf_write_sup_cid(GF_BitStream *bs, GF_SCIDesc *scid)
3183 {
3184 	GF_Err e;
3185 	u32 size;
3186 	if (!scid) return GF_BAD_PARAM;
3187 	e = gf_odf_size_descriptor((GF_Descriptor *)scid, &size);
3188 	if (e) return e;
3189 	e = gf_odf_write_base_descriptor(bs, scid->tag, size);
3190 	if (e) return e;
3191 	gf_bs_write_int(bs, scid->languageCode, 24);
3192 	OD_WriteUTF8String(bs, scid->supplContentIdentifierTitle, GF_TRUE);
3193 	OD_WriteUTF8String(bs, scid->supplContentIdentifierValue, GF_TRUE);
3194 	return GF_OK;
3195 }
3196 
3197 
3198 /*IPMPX stuff*/
gf_odf_new_ipmp_tool_list()3199 GF_Descriptor *gf_odf_new_ipmp_tool_list()
3200 {
3201 	GF_IPMP_ToolList*newDesc = (GF_IPMP_ToolList*)gf_malloc(sizeof(GF_IPMP_ToolList));
3202 	if (!newDesc) return NULL;
3203 	newDesc->ipmp_tools = gf_list_new();
3204 	newDesc->tag = GF_ODF_IPMP_TL_TAG;
3205 	return (GF_Descriptor *)newDesc;
3206 }
3207 
gf_odf_del_ipmp_tool_list(GF_IPMP_ToolList * ipmptl)3208 GF_Err gf_odf_del_ipmp_tool_list(GF_IPMP_ToolList *ipmptl)
3209 {
3210 	if (!ipmptl) return GF_BAD_PARAM;
3211 
3212 	while (gf_list_count(ipmptl->ipmp_tools)) {
3213 		GF_IPMP_Tool *t = (GF_IPMP_Tool *)gf_list_get(ipmptl->ipmp_tools, 0);
3214 		gf_list_rem(ipmptl->ipmp_tools, 0);
3215 		if (t->tool_url) gf_free(t->tool_url);
3216 		gf_free(t);
3217 	}
3218 	gf_list_del(ipmptl->ipmp_tools);
3219 	gf_free(ipmptl);
3220 	return GF_OK;
3221 }
3222 
gf_odf_read_ipmp_tool_list(GF_BitStream * bs,GF_IPMP_ToolList * ipmptl,u32 DescSize)3223 GF_Err gf_odf_read_ipmp_tool_list(GF_BitStream *bs, GF_IPMP_ToolList *ipmptl, u32 DescSize)
3224 {
3225 	GF_Err e;
3226 	u32 tmpSize;
3227 	u32 nbBytes = 0;
3228 	if (!ipmptl) return GF_BAD_PARAM;
3229 
3230 	while (nbBytes < DescSize) {
3231 		GF_Descriptor *tmp = NULL;
3232 		e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
3233 		if (e) return e;
3234 		if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
3235 		e = gf_list_add(ipmptl->ipmp_tools, tmp);
3236 		if (e) return e;
3237 		nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
3238 	}
3239 	if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3240 	return GF_OK;
3241 }
3242 
3243 
gf_odf_size_ipmp_tool_list(GF_IPMP_ToolList * ipmptl,u32 * outSize)3244 GF_Err gf_odf_size_ipmp_tool_list(GF_IPMP_ToolList *ipmptl, u32 *outSize)
3245 {
3246 	if (!ipmptl) return GF_BAD_PARAM;
3247 	*outSize = 0;
3248 	return gf_odf_size_descriptor_list(ipmptl->ipmp_tools, outSize);
3249 }
3250 
gf_odf_write_ipmp_tool_list(GF_BitStream * bs,GF_IPMP_ToolList * ipmptl)3251 GF_Err gf_odf_write_ipmp_tool_list(GF_BitStream *bs, GF_IPMP_ToolList *ipmptl)
3252 {
3253 	GF_Err e;
3254 	u32 size;
3255 	if (!ipmptl) return GF_BAD_PARAM;
3256 	e = gf_odf_size_descriptor((GF_Descriptor *)ipmptl, &size);
3257 	if (e) return e;
3258 	e = gf_odf_write_base_descriptor(bs, ipmptl->tag, size);
3259 	if (e) return e;
3260 	return gf_odf_write_descriptor_list(bs, ipmptl->ipmp_tools);
3261 }
3262 
gf_odf_new_ipmp_tool()3263 GF_Descriptor *gf_odf_new_ipmp_tool()
3264 {
3265 	GF_IPMP_Tool *newDesc = (GF_IPMP_Tool*)gf_malloc(sizeof(GF_IPMP_Tool));
3266 	if (!newDesc) return NULL;
3267 	memset(newDesc, 0, sizeof(GF_IPMP_Tool));
3268 	newDesc->tag = GF_ODF_IPMP_TL_TAG;
3269 	return (GF_Descriptor *)newDesc;
3270 }
3271 
gf_odf_del_ipmp_tool(GF_IPMP_Tool * ipmpt)3272 GF_Err gf_odf_del_ipmp_tool(GF_IPMP_Tool *ipmpt)
3273 {
3274 	if (!ipmpt) return GF_BAD_PARAM;
3275 	if (ipmpt->tool_url) gf_free(ipmpt->tool_url);
3276 	gf_free(ipmpt);
3277 	return GF_OK;
3278 }
3279 
gf_odf_read_ipmp_tool(GF_BitStream * bs,GF_IPMP_Tool * ipmpt,u32 DescSize)3280 GF_Err gf_odf_read_ipmp_tool(GF_BitStream *bs, GF_IPMP_Tool *ipmpt, u32 DescSize)
3281 {
3282 	Bool is_alt, is_param;
3283 	u32 nbBytes = 0;
3284 	if (!ipmpt) return GF_BAD_PARAM;
3285 	gf_bs_read_data(bs, (char*)ipmpt->IPMP_ToolID, 16);
3286 	is_alt = (Bool)gf_bs_read_int(bs, 1);
3287 	is_param = (Bool)gf_bs_read_int(bs, 1);
3288 	gf_bs_read_int(bs, 6);
3289 	nbBytes = 17;
3290 
3291 	if (is_alt) {
3292 		u32 i;
3293 		ipmpt->num_alternate = gf_bs_read_int(bs, 8);
3294 		nbBytes += 1;
3295 		for (i = 0; i<ipmpt->num_alternate; i++) {
3296 			gf_bs_read_data(bs, (char*)ipmpt->specificToolID[i], 16);
3297 			nbBytes += 16;
3298 			if (nbBytes>DescSize) break;
3299 		}
3300 	}
3301 	if (nbBytes>DescSize) return GF_ODF_INVALID_DESCRIPTOR;
3302 
3303 	if (is_param) {}
3304 
3305 	if (nbBytes<DescSize) {
3306 		u32 s;
3307 		nbBytes += gf_ipmpx_array_size(bs, &s);
3308 		if (s) {
3309 			ipmpt->tool_url = (char*)gf_malloc(sizeof(char)*(s + 1));
3310 			gf_bs_read_data(bs, ipmpt->tool_url, s);
3311 			ipmpt->tool_url[s] = 0;
3312 			nbBytes += s;
3313 		}
3314 	}
3315 
3316 	if (nbBytes != DescSize) return GF_NON_COMPLIANT_BITSTREAM;
3317 	return GF_OK;
3318 }
3319 
3320 
gf_odf_size_ipmp_tool(GF_IPMP_Tool * ipmpt,u32 * outSize)3321 GF_Err gf_odf_size_ipmp_tool(GF_IPMP_Tool *ipmpt, u32 *outSize)
3322 {
3323 	if (!ipmpt) return GF_BAD_PARAM;
3324 	*outSize = 17;
3325 	if (ipmpt->num_alternate) *outSize += 1 + 16 * ipmpt->num_alternate;
3326 
3327 	if (ipmpt->tool_url) {
3328 		u32 s = (u32)strlen(ipmpt->tool_url);
3329 		*outSize += gf_odf_size_field_size(s) - 1 + s;
3330 	}
3331 	return GF_OK;
3332 }
3333 
gf_odf_write_ipmp_tool(GF_BitStream * bs,GF_IPMP_Tool * ipmpt)3334 GF_Err gf_odf_write_ipmp_tool(GF_BitStream *bs, GF_IPMP_Tool *ipmpt)
3335 {
3336 	GF_Err e;
3337 	u32 size;
3338 	if (!ipmpt) return GF_BAD_PARAM;
3339 	e = gf_odf_size_descriptor((GF_Descriptor *)ipmpt, &size);
3340 	if (e) return e;
3341 	e = gf_odf_write_base_descriptor(bs, ipmpt->tag, size);
3342 	if (e) return e;
3343 
3344 	gf_bs_write_data(bs, (char*)ipmpt->IPMP_ToolID, 16);
3345 	gf_bs_write_int(bs, ipmpt->num_alternate ? 1 : 0, 1);
3346 	gf_bs_write_int(bs, 0, 1);
3347 	gf_bs_write_int(bs, 0, 6);
3348 
3349 	if (ipmpt->num_alternate) {
3350 		u32 i;
3351 		gf_bs_write_int(bs, ipmpt->num_alternate, 8);
3352 		for (i = 0; i<ipmpt->num_alternate; i++) gf_bs_write_data(bs, (char*)ipmpt->specificToolID[i], 16);
3353 	}
3354 	if (ipmpt->tool_url) gf_ipmpx_write_array(bs, ipmpt->tool_url, (u32)strlen(ipmpt->tool_url));
3355 	return GF_OK;
3356 }
3357 
3358 #endif /*GPAC_MINIMAL_ODF*/
3359