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 / ISO Media File Format 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/isomedia_dev.h>
27 
28 #ifndef GPAC_DISABLE_ISOM
29 
gppa_del(GF_Box * s)30 void gppa_del(GF_Box *s)
31 {
32 	GF_3GPPAudioSampleEntryBox *ptr = (GF_3GPPAudioSampleEntryBox *)s;
33 	if (ptr == NULL) return;
34 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
35 
36 	if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info);
37 	gf_free(ptr);
38 }
39 
40 
gppa_Read(GF_Box * s,GF_BitStream * bs)41 GF_Err gppa_Read(GF_Box *s, GF_BitStream *bs)
42 {
43 	GF_Err e;
44 	GF_3GPPAudioSampleEntryBox *ptr = (GF_3GPPAudioSampleEntryBox *)s;
45 	e = gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox*)s, bs);
46 	if (e) return e;
47 	e = gf_isom_parse_box((GF_Box **)&ptr->info, bs);
48 	if (e) return e;
49 	ptr->info->cfg.type = ptr->type;
50 	return GF_OK;
51 }
52 
gppa_New(u32 type)53 GF_Box *gppa_New(u32 type)
54 {
55 	ISOM_DECL_BOX_ALLOC(GF_3GPPAudioSampleEntryBox, type);
56 	gf_isom_audio_sample_entry_init((GF_AudioSampleEntryBox*)tmp);
57 	return (GF_Box *)tmp;
58 }
59 
60 #ifndef GPAC_DISABLE_ISOM_WRITE
61 
gppa_Write(GF_Box * s,GF_BitStream * bs)62 GF_Err gppa_Write(GF_Box *s, GF_BitStream *bs)
63 {
64 	GF_Err e;
65 	GF_3GPPAudioSampleEntryBox *ptr = (GF_3GPPAudioSampleEntryBox *)s;
66 	e = gf_isom_box_write_header(s, bs);
67 	if (e) return e;
68 
69 	gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs);
70 	return gf_isom_box_write((GF_Box *)ptr->info, bs);
71 }
72 
gppa_Size(GF_Box * s)73 GF_Err gppa_Size(GF_Box *s)
74 {
75 	GF_Err e;
76 	GF_3GPPAudioSampleEntryBox *ptr = (GF_3GPPAudioSampleEntryBox *)s;
77 	e = gf_isom_box_get_size(s);
78 	if (e) return e;
79 	gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox*)s);
80 	e = gf_isom_box_size((GF_Box *)ptr->info);
81 	if (e) return e;
82 	ptr->size += ptr->info->size;
83 	return GF_OK;
84 }
85 
86 #endif /*GPAC_DISABLE_ISOM_WRITE*/
87 
88 
gppv_New(u32 type)89 GF_Box *gppv_New(u32 type)
90 {
91 	ISOM_DECL_BOX_ALLOC(GF_3GPPVisualSampleEntryBox, type);
92 	gf_isom_video_sample_entry_init((GF_VisualSampleEntryBox *)tmp);
93 	return (GF_Box *)tmp;
94 }
gppv_del(GF_Box * s)95 void gppv_del(GF_Box *s)
96 {
97 	GF_3GPPVisualSampleEntryBox *ptr = (GF_3GPPVisualSampleEntryBox *)s;
98 	if (ptr == NULL) return;
99 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)ptr);
100 	if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info);
101 	gf_free(ptr);
102 }
103 
gppv_Read(GF_Box * s,GF_BitStream * bs)104 GF_Err gppv_Read(GF_Box *s, GF_BitStream *bs)
105 {
106 	GF_Err e;
107 	GF_3GPPVisualSampleEntryBox *ptr = (GF_3GPPVisualSampleEntryBox *)s;
108 	e = gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *)ptr, bs);
109 	if (e) return e;
110 	/*FIXME - check for any other boxes...*/
111 	e = gf_isom_parse_box((GF_Box **)&ptr->info, bs);
112 	return e;
113 }
114 
115 #ifndef GPAC_DISABLE_ISOM_WRITE
116 
gppv_Write(GF_Box * s,GF_BitStream * bs)117 GF_Err gppv_Write(GF_Box *s, GF_BitStream *bs)
118 {
119 	GF_Err e;
120 	GF_3GPPVisualSampleEntryBox *ptr = (GF_3GPPVisualSampleEntryBox*)s;
121 	e = gf_isom_box_write_header(s, bs);
122 	if (e) return e;
123 	gf_isom_video_sample_entry_write((GF_VisualSampleEntryBox *)s, bs);
124 	e = gf_isom_box_write((GF_Box *)ptr->info, bs);
125 	if (e) return e;
126 	return GF_OK;
127 }
128 
gppv_Size(GF_Box * s)129 GF_Err gppv_Size(GF_Box *s)
130 {
131 	GF_Err e;
132 	GF_3GPPVisualSampleEntryBox *ptr = (GF_3GPPVisualSampleEntryBox*)s;
133 	e = gf_isom_box_get_size(s);
134 	if (e) return e;
135 	gf_isom_video_sample_entry_size((GF_VisualSampleEntryBox *)s);
136 	e = gf_isom_box_size((GF_Box *)ptr->info);
137 	if (e) return e;
138 	ptr->size += ptr->info->size;
139 	return GF_OK;
140 }
141 
142 #endif /*GPAC_DISABLE_ISOM_WRITE*/
143 
144 
gppc_New(u32 type)145 GF_Box *gppc_New(u32 type)
146 {
147 	ISOM_DECL_BOX_ALLOC(GF_3GPPConfigBox, type);
148 	return (GF_Box *)tmp;
149 }
150 
gppc_del(GF_Box * s)151 void gppc_del(GF_Box *s)
152 {
153 	GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s;
154 	if (ptr == NULL) return;
155 	gf_free(ptr);
156 }
157 
158 
gppc_Read(GF_Box * s,GF_BitStream * bs)159 GF_Err gppc_Read(GF_Box *s, GF_BitStream *bs)
160 {
161 	GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s;
162 	if (ptr == NULL) return GF_BAD_PARAM;
163 	memset(&ptr->cfg, 0, sizeof(GF_3GPConfig));
164 
165 	ptr->cfg.vendor = gf_bs_read_u32(bs);
166 	ptr->cfg.decoder_version = gf_bs_read_u8(bs);
167 
168 	switch (ptr->type) {
169 	case GF_ISOM_BOX_TYPE_D263:
170 		ptr->cfg.H263_level = gf_bs_read_u8(bs);
171 		ptr->cfg.H263_profile = gf_bs_read_u8(bs);
172 		break;
173 	case GF_ISOM_BOX_TYPE_DAMR:
174 		ptr->cfg.AMR_mode_set = gf_bs_read_u16(bs);
175 		ptr->cfg.AMR_mode_change_period = gf_bs_read_u8(bs);
176 		ptr->cfg.frames_per_sample = gf_bs_read_u8(bs);
177 		break;
178 	case GF_ISOM_BOX_TYPE_DEVC:
179 	case GF_ISOM_BOX_TYPE_DQCP:
180 	case GF_ISOM_BOX_TYPE_DSMV:
181 		ptr->cfg.frames_per_sample = gf_bs_read_u8(bs);
182 		break;
183 	}
184 	return GF_OK;
185 }
186 
187 #ifndef GPAC_DISABLE_ISOM_WRITE
188 
gppc_Write(GF_Box * s,GF_BitStream * bs)189 GF_Err gppc_Write(GF_Box *s, GF_BitStream *bs)
190 {
191 	GF_Err e;
192 	GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s;
193 	e = gf_isom_box_write_header(s, bs);
194 	if (e) return e;
195 
196 	gf_bs_write_u32(bs, ptr->cfg.vendor);
197 	gf_bs_write_u8(bs, ptr->cfg.decoder_version);
198 	switch (ptr->cfg.type) {
199 	case GF_ISOM_SUBTYPE_3GP_H263:
200 		gf_bs_write_u8(bs, ptr->cfg.H263_level);
201 		gf_bs_write_u8(bs, ptr->cfg.H263_profile);
202 		break;
203 	case GF_ISOM_SUBTYPE_3GP_AMR:
204 	case GF_ISOM_SUBTYPE_3GP_AMR_WB:
205 		gf_bs_write_u16(bs, ptr->cfg.AMR_mode_set);
206 		gf_bs_write_u8(bs, ptr->cfg.AMR_mode_change_period);
207 		gf_bs_write_u8(bs, ptr->cfg.frames_per_sample);
208 		break;
209 	case GF_ISOM_SUBTYPE_3GP_EVRC:
210 	case GF_ISOM_SUBTYPE_3GP_QCELP:
211 	case GF_ISOM_SUBTYPE_3GP_SMV:
212 		gf_bs_write_u8(bs, ptr->cfg.frames_per_sample);
213 		break;
214 	}
215 	return GF_OK;
216 }
217 
gppc_Size(GF_Box * s)218 GF_Err gppc_Size(GF_Box *s)
219 {
220 	GF_Err e;
221 	GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s;
222 
223 	e = gf_isom_box_get_size(s);
224 	if (e) return e;
225 	s->size += 5;
226 	switch (ptr->cfg.type) {
227 	case GF_ISOM_SUBTYPE_3GP_H263:
228 		s->size += 2;
229 		break;
230 	case GF_ISOM_SUBTYPE_3GP_AMR:
231 	case GF_ISOM_SUBTYPE_3GP_AMR_WB:
232 		s->size += 4;
233 		break;
234 	case GF_ISOM_SUBTYPE_3GP_EVRC:
235 	case GF_ISOM_SUBTYPE_3GP_QCELP:
236 	case GF_ISOM_SUBTYPE_3GP_SMV:
237 		s->size += 1;
238 		break;
239 	}
240 	return GF_OK;
241 }
242 
243 #endif /*GPAC_DISABLE_ISOM_WRITE*/
244 
245 
ftab_New()246 GF_Box *ftab_New()
247 {
248 	ISOM_DECL_BOX_ALLOC(GF_FontTableBox, GF_ISOM_BOX_TYPE_FTAB);
249 	return (GF_Box *)tmp;
250 }
ftab_del(GF_Box * s)251 void ftab_del(GF_Box *s)
252 {
253 	GF_FontTableBox *ptr = (GF_FontTableBox *)s;
254 	if (ptr->fonts) {
255 		u32 i;
256 		for (i = 0; i<ptr->entry_count; i++)
257 			if (ptr->fonts[i].fontName) gf_free(ptr->fonts[i].fontName);
258 		gf_free(ptr->fonts);
259 	}
260 	gf_free(ptr);
261 }
ftab_Read(GF_Box * s,GF_BitStream * bs)262 GF_Err ftab_Read(GF_Box *s, GF_BitStream *bs)
263 {
264 	u32 i;
265 	GF_FontTableBox *ptr = (GF_FontTableBox *)s;
266 	ptr->entry_count = gf_bs_read_u16(bs);
267 	ptr->size -= 2;
268 	if (ptr->size<ptr->entry_count * 3) {
269 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Corrupted ftap box, skipping\n"));
270 		ptr->entry_count = 0;
271 		return GF_OK;
272 	}
273 	ptr->fonts = (GF_FontRecord *)gf_malloc(sizeof(GF_FontRecord)*ptr->entry_count);
274 	memset(ptr->fonts, 0, sizeof(GF_FontRecord)*ptr->entry_count);
275 	for (i = 0; i<ptr->entry_count; i++) {
276 		u32 len;
277 		ptr->fonts[i].fontID = gf_bs_read_u16(bs);
278 		len = gf_bs_read_u8(bs);
279 		if (len) {
280 			ptr->fonts[i].fontName = (char *)gf_malloc(sizeof(char)*(len + 1));
281 			gf_bs_read_data(bs, ptr->fonts[i].fontName, len);
282 			ptr->fonts[i].fontName[len] = 0;
283 		}
284 	}
285 	return GF_OK;
286 }
287 
288 #ifndef GPAC_DISABLE_ISOM_WRITE
ftab_Write(GF_Box * s,GF_BitStream * bs)289 GF_Err ftab_Write(GF_Box *s, GF_BitStream *bs)
290 {
291 	GF_Err e;
292 	u32 i;
293 	GF_FontTableBox *ptr = (GF_FontTableBox *)s;
294 	e = gf_isom_box_write_header(s, bs);
295 	if (e) return e;
296 	gf_bs_write_u16(bs, ptr->entry_count);
297 	for (i = 0; i<ptr->entry_count; i++) {
298 		gf_bs_write_u16(bs, ptr->fonts[i].fontID);
299 		if (ptr->fonts[i].fontName) {
300 			u32 len = (u32)strlen(ptr->fonts[i].fontName);
301 			gf_bs_write_u8(bs, len);
302 			gf_bs_write_data(bs, ptr->fonts[i].fontName, len);
303 		}
304 		else {
305 			gf_bs_write_u8(bs, 0);
306 		}
307 	}
308 	return GF_OK;
309 }
ftab_Size(GF_Box * s)310 GF_Err ftab_Size(GF_Box *s)
311 {
312 	u32 i;
313 	GF_FontTableBox *ptr = (GF_FontTableBox *)s;
314 	GF_Err e = gf_isom_box_get_size(s);
315 	if (e) return e;
316 	s->size += 2;
317 	for (i = 0; i<ptr->entry_count; i++) {
318 		s->size += 3;
319 		if (ptr->fonts[i].fontName) s->size += strlen(ptr->fonts[i].fontName);
320 	}
321 	return GF_OK;
322 }
323 
324 #endif /*GPAC_DISABLE_ISOM_WRITE*/
325 
326 
327 
text_New()328 GF_Box *text_New()
329 {
330 	ISOM_DECL_BOX_ALLOC(GF_TextSampleEntryBox, GF_ISOM_BOX_TYPE_TEXT);
331 	return (GF_Box *)tmp;
332 }
333 
text_del(GF_Box * s)334 void text_del(GF_Box *s)
335 {
336 	GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s;
337 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
338 
339 	if (ptr->textName)
340 		gf_free(ptr->textName);
341 	gf_free(ptr);
342 }
343 
tx3g_New()344 GF_Box *tx3g_New()
345 {
346 	ISOM_DECL_BOX_ALLOC(GF_Tx3gSampleEntryBox, GF_ISOM_BOX_TYPE_TX3G);
347 	return (GF_Box *)tmp;
348 }
349 
tx3g_del(GF_Box * s)350 void tx3g_del(GF_Box *s)
351 {
352 	GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s;
353 
354 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
355 
356 	if (ptr->font_table)
357 		gf_isom_box_del((GF_Box *)ptr->font_table);
358 	gf_free(ptr);
359 }
360 
gpp_read_rgba(GF_BitStream * bs)361 static u32 gpp_read_rgba(GF_BitStream *bs)
362 {
363 	u8 r, g, b, a;
364 	u32 col;
365 	r = gf_bs_read_u8(bs);
366 	g = gf_bs_read_u8(bs);
367 	b = gf_bs_read_u8(bs);
368 	a = gf_bs_read_u8(bs);
369 	col = a;
370 	col <<= 8;
371 	col |= r;
372 	col <<= 8;
373 	col |= g;
374 	col <<= 8;
375 	col |= b;
376 	return col;
377 }
378 
379 #define GPP_BOX_SIZE	8
gpp_read_box(GF_BitStream * bs,GF_BoxRecord * rec)380 static void gpp_read_box(GF_BitStream *bs, GF_BoxRecord *rec)
381 {
382 	rec->top = gf_bs_read_u16(bs);
383 	rec->left = gf_bs_read_u16(bs);
384 	rec->bottom = gf_bs_read_u16(bs);
385 	rec->right = gf_bs_read_u16(bs);
386 }
387 
388 #define GPP_STYLE_SIZE	12
gpp_read_style(GF_BitStream * bs,GF_StyleRecord * rec)389 static void gpp_read_style(GF_BitStream *bs, GF_StyleRecord *rec)
390 {
391 	rec->startCharOffset = gf_bs_read_u16(bs);
392 	rec->endCharOffset = gf_bs_read_u16(bs);
393 	rec->fontID = gf_bs_read_u16(bs);
394 	rec->style_flags = gf_bs_read_u8(bs);
395 	rec->font_size = gf_bs_read_u8(bs);
396 	rec->text_color = gpp_read_rgba(bs);
397 }
398 
tx3g_Read(GF_Box * s,GF_BitStream * bs)399 GF_Err tx3g_Read(GF_Box *s, GF_BitStream *bs)
400 {
401 	GF_Err e;
402 	GF_Box *a;
403 	GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s;
404 
405 	if (ptr->size < 18 + GPP_BOX_SIZE + GPP_STYLE_SIZE) return GF_ISOM_INVALID_FILE;
406 
407 	gf_bs_read_data(bs, ptr->reserved, 6);
408 	ptr->dataReferenceIndex = gf_bs_read_u16(bs);
409 	ptr->displayFlags = gf_bs_read_u32(bs);
410 	ptr->horizontal_justification = gf_bs_read_u8(bs);
411 	ptr->vertical_justification = gf_bs_read_u8(bs);
412 	ptr->back_color = gpp_read_rgba(bs);
413 	gpp_read_box(bs, &ptr->default_box);
414 	gpp_read_style(bs, &ptr->default_style);
415 	ptr->size -= 18 + GPP_BOX_SIZE + GPP_STYLE_SIZE;
416 
417 	while (ptr->size >= 8) {
418 		e = gf_isom_parse_box(&a, bs);
419 		if (e) return e;
420 		if (ptr->size<a->size) {
421 			GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Box \"%s\" larger than remaining bytes in tx3g - ignoring box\n", gf_4cc_to_str(a->type)));
422 			ptr->size = 0;
423 			gf_isom_box_del(a);
424 			return GF_OK;
425 		}
426 
427 		ptr->size -= a->size;
428 		if (a->type == GF_ISOM_BOX_TYPE_FTAB) {
429 			if (ptr->font_table) gf_isom_box_del((GF_Box *)ptr->font_table);
430 			ptr->font_table = (GF_FontTableBox *)a;
431 		}
432 		else {
433 			e = gf_isom_box_add_default(s, a);
434 			if (e) return e;
435 		}
436 	}
437 	return GF_OK;
438 }
439 
440 /*this is a quicktime specific box - see apple documentation*/
text_Read(GF_Box * s,GF_BitStream * bs)441 GF_Err text_Read(GF_Box *s, GF_BitStream *bs)
442 {
443 	u16 pSize;
444 	GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s;
445 	gf_bs_read_data(bs, ptr->reserved, 6);
446 	ptr->dataReferenceIndex = gf_bs_read_u16(bs);
447 
448 	ptr->displayFlags = gf_bs_read_u32(bs);			/*Display flags*/
449 	ptr->textJustification = gf_bs_read_u32(bs);	/*Text justification*/
450 	gf_bs_read_data(bs, ptr->background_color, 6);	/*Background color*/
451 	gpp_read_box(bs, &ptr->default_box);			/*Default text box*/
452 	gf_bs_read_data(bs, ptr->reserved1, 8);			/*Reserved*/
453 	ptr->fontNumber = gf_bs_read_u16(bs);			/*Font number*/
454 	ptr->fontFace = gf_bs_read_u16(bs);			/*Font face*/
455 	ptr->reserved2 = gf_bs_read_u8(bs);			/*Reserved*/
456 	ptr->reserved3 = gf_bs_read_u16(bs);			/*Reserved*/
457 	gf_bs_read_data(bs, ptr->foreground_color, 6);	/*Foreground color*/
458 	if (ptr->size < 51)
459 		return GF_ISOM_INVALID_FILE;
460 	ptr->size -= 51;
461 	if (!ptr->size)
462 		return GF_OK; /*ffmpeg compatibility with iPod streams: no pascal string*/
463 
464 	pSize = gf_bs_read_u8(bs); /*a Pascal string begins with its size: get textName size*/
465 	ptr->size -= 1;
466 	if (ptr->size < pSize) {
467 		u32 s = pSize;
468 		size_t i = 0;
469 		GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] text box doesn't use a Pascal string: trying to decode anyway.\n"));
470 		ptr->textName = (char*)gf_malloc((u32)ptr->size + 1 + 1);
471 		do {
472 			char c = (char)s;
473 			if (c == '\0') {
474 				break;
475 			}
476 			else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
477 				ptr->textName[i] = c;
478 			}
479 			else {
480 				gf_free(ptr->textName);
481 				ptr->textName = NULL;
482 				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] text box doesn't use a Pascal string and contains non-chars. Abort.\n"));
483 				return GF_ISOM_INVALID_FILE;
484 			}
485 			i++;
486 			if (!ptr->size)
487 				break;
488 			ptr->size--;
489 			s = gf_bs_read_u8(bs);
490 		} while (s);
491 
492 		ptr->textName[i] = '\0';				/*Font name*/
493 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] text box doesn't use a Pascal string: \"%s\" detected.\n", ptr->textName));
494 		return GF_OK;
495 	}
496 	if (pSize) {
497 		ptr->textName = (char*)gf_malloc(pSize + 1 * sizeof(char));
498 		if (gf_bs_read_data(bs, ptr->textName, pSize) != pSize) {
499 			gf_free(ptr->textName);
500 			ptr->textName = NULL;
501 			return GF_ISOM_INVALID_FILE;
502 		}
503 		ptr->textName[pSize] = '\0';				/*Font name*/
504 	}
505 	ptr->size -= pSize;
506 
507 	return GF_OK;
508 }
509 
gpp_write_rgba(GF_BitStream * bs,u32 col)510 void gpp_write_rgba(GF_BitStream *bs, u32 col)
511 {
512 	gf_bs_write_u8(bs, (col >> 16) & 0xFF);
513 	gf_bs_write_u8(bs, (col >> 8) & 0xFF);
514 	gf_bs_write_u8(bs, (col) & 0xFF);
515 	gf_bs_write_u8(bs, (col >> 24) & 0xFF);
516 }
517 
gpp_write_box(GF_BitStream * bs,GF_BoxRecord * rec)518 void gpp_write_box(GF_BitStream *bs, GF_BoxRecord *rec)
519 {
520 	gf_bs_write_u16(bs, rec->top);
521 	gf_bs_write_u16(bs, rec->left);
522 	gf_bs_write_u16(bs, rec->bottom);
523 	gf_bs_write_u16(bs, rec->right);
524 }
525 
526 #define GPP_STYLE_SIZE	12
gpp_write_style(GF_BitStream * bs,GF_StyleRecord * rec)527 void gpp_write_style(GF_BitStream *bs, GF_StyleRecord *rec)
528 {
529 	gf_bs_write_u16(bs, rec->startCharOffset);
530 	gf_bs_write_u16(bs, rec->endCharOffset);
531 	gf_bs_write_u16(bs, rec->fontID);
532 	gf_bs_write_u8(bs, rec->style_flags);
533 	gf_bs_write_u8(bs, rec->font_size);
534 	gpp_write_rgba(bs, rec->text_color);
535 }
536 
537 #ifndef GPAC_DISABLE_ISOM_WRITE
538 
tx3g_Write(GF_Box * s,GF_BitStream * bs)539 GF_Err tx3g_Write(GF_Box *s, GF_BitStream *bs)
540 {
541 	GF_Err e;
542 	GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s;
543 
544 	e = gf_isom_box_write_header(s, bs);
545 	if (e) return e;
546 	gf_bs_write_data(bs, ptr->reserved, 6);
547 	gf_bs_write_u16(bs, ptr->dataReferenceIndex);
548 	gf_bs_write_u32(bs, ptr->displayFlags);
549 	gf_bs_write_u8(bs, ptr->horizontal_justification);
550 	gf_bs_write_u8(bs, ptr->vertical_justification);
551 	gpp_write_rgba(bs, ptr->back_color);
552 	gpp_write_box(bs, &ptr->default_box);
553 	gpp_write_style(bs, &ptr->default_style);
554 	return gf_isom_box_write((GF_Box *)ptr->font_table, bs);
555 }
556 
text_Write(GF_Box * s,GF_BitStream * bs)557 GF_Err text_Write(GF_Box *s, GF_BitStream *bs)
558 {
559 	GF_Err e;
560 	u16 pSize;
561 	GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s;
562 
563 	e = gf_isom_box_write_header(s, bs);
564 	if (e) return e;
565 	gf_bs_write_data(bs, ptr->reserved, 6);
566 	gf_bs_write_u16(bs, ptr->dataReferenceIndex);
567 	gf_bs_write_u32(bs, ptr->displayFlags);			/*Display flags*/
568 	gf_bs_write_u32(bs, ptr->textJustification);	/*Text justification*/
569 	gf_bs_write_data(bs, ptr->background_color, 6);	/*Background color*/
570 	gpp_write_box(bs, &ptr->default_box);			/*Default text box*/
571 	gf_bs_write_data(bs, ptr->reserved1, 8);		/*Reserved*/
572 	gf_bs_write_u16(bs, ptr->fontNumber);			/*Font number*/
573 	gf_bs_write_u16(bs, ptr->fontFace);				/*Font face*/
574 	gf_bs_write_u8(bs, ptr->reserved2);				/*Reserved*/
575 	gf_bs_write_u16(bs, ptr->reserved3);			/*Reserved*/
576 	gf_bs_write_data(bs, ptr->foreground_color, 6);	/*Foreground color*/
577 													//pSize assignment below is not a mistake
578 	if (ptr->textName && (pSize = (u16)strlen(ptr->textName))) {
579 		gf_bs_write_u8(bs, pSize);					/*a Pascal string begins with its size*/
580 		gf_bs_write_data(bs, ptr->textName, pSize);	/*Font name*/
581 	}
582 	else {
583 		gf_bs_write_u8(bs, 0);
584 	}
585 	return GF_OK;
586 }
587 
tx3g_Size(GF_Box * s)588 GF_Err tx3g_Size(GF_Box *s)
589 {
590 	GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s;
591 	GF_Err e = gf_isom_box_get_size(s);
592 	if (e) return e;
593 	/*base + this  + box + style*/
594 	s->size += 18 + GPP_BOX_SIZE + GPP_STYLE_SIZE;
595 	if (ptr->font_table) {
596 		e = gf_isom_box_size((GF_Box *)ptr->font_table);
597 		if (e) return e;
598 		s->size += ptr->font_table->size;
599 	}
600 	return GF_OK;
601 }
602 
text_Size(GF_Box * s)603 GF_Err text_Size(GF_Box *s)
604 {
605 	GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s;
606 	GF_Err e = gf_isom_box_get_size(s);
607 	if (e) return e;
608 	/*base + this + string length*/
609 	s->size += 51 + 1;
610 	if (ptr->textName)
611 		s->size += strlen(ptr->textName);
612 	return GF_OK;
613 }
614 
615 #endif
616 
styl_New()617 GF_Box *styl_New()
618 {
619 	ISOM_DECL_BOX_ALLOC(GF_TextStyleBox, GF_ISOM_BOX_TYPE_STYL);
620 	return (GF_Box *)tmp;
621 }
622 
styl_del(GF_Box * s)623 void styl_del(GF_Box *s)
624 {
625 	GF_TextStyleBox*ptr = (GF_TextStyleBox*)s;
626 	if (ptr->styles) gf_free(ptr->styles);
627 	gf_free(ptr);
628 }
629 
styl_Read(GF_Box * s,GF_BitStream * bs)630 GF_Err styl_Read(GF_Box *s, GF_BitStream *bs)
631 {
632 	u32 i;
633 	GF_TextStyleBox*ptr = (GF_TextStyleBox*)s;
634 	ptr->entry_count = gf_bs_read_u16(bs);
635 	if (ptr->entry_count) {
636 		ptr->styles = (GF_StyleRecord*)gf_malloc(sizeof(GF_StyleRecord)*ptr->entry_count);
637 		for (i = 0; i<ptr->entry_count; i++) {
638 			gpp_read_style(bs, &ptr->styles[i]);
639 		}
640 	}
641 	return GF_OK;
642 }
643 
644 #ifndef GPAC_DISABLE_ISOM_WRITE
styl_Write(GF_Box * s,GF_BitStream * bs)645 GF_Err styl_Write(GF_Box *s, GF_BitStream *bs)
646 {
647 	GF_Err e;
648 	u32 i;
649 	GF_TextStyleBox*ptr = (GF_TextStyleBox*)s;
650 	e = gf_isom_box_write_header(s, bs);
651 	if (e) return e;
652 
653 	gf_bs_write_u16(bs, ptr->entry_count);
654 	for (i = 0; i<ptr->entry_count; i++) gpp_write_style(bs, &ptr->styles[i]);
655 	return GF_OK;
656 }
657 
styl_Size(GF_Box * s)658 GF_Err styl_Size(GF_Box *s)
659 {
660 	GF_TextStyleBox*ptr = (GF_TextStyleBox*)s;
661 	GF_Err e = gf_isom_box_get_size(s);
662 	if (e) return e;
663 	s->size += 2 + ptr->entry_count * GPP_STYLE_SIZE;
664 	return GF_OK;
665 }
666 
667 #endif /*GPAC_DISABLE_ISOM_WRITE*/
668 
hlit_New()669 GF_Box *hlit_New()
670 {
671 	ISOM_DECL_BOX_ALLOC(GF_TextHighlightBox, GF_ISOM_BOX_TYPE_HLIT);
672 	return (GF_Box *)tmp;
673 }
674 
hlit_del(GF_Box * s)675 void hlit_del(GF_Box *s)
676 {
677 	gf_free(s);
678 }
679 
hlit_Read(GF_Box * s,GF_BitStream * bs)680 GF_Err hlit_Read(GF_Box *s, GF_BitStream *bs)
681 {
682 	GF_TextHighlightBox *ptr = (GF_TextHighlightBox *)s;
683 	ptr->startcharoffset = gf_bs_read_u16(bs);
684 	ptr->endcharoffset = gf_bs_read_u16(bs);
685 	return GF_OK;
686 }
687 
688 #ifndef GPAC_DISABLE_ISOM_WRITE
hlit_Write(GF_Box * s,GF_BitStream * bs)689 GF_Err hlit_Write(GF_Box *s, GF_BitStream *bs)
690 {
691 	GF_Err e;
692 	GF_TextHighlightBox *ptr = (GF_TextHighlightBox *)s;
693 	e = gf_isom_box_write_header(s, bs);
694 	if (e) return e;
695 	gf_bs_write_u16(bs, ptr->startcharoffset);
696 	gf_bs_write_u16(bs, ptr->endcharoffset);
697 	return GF_OK;
698 }
699 
hlit_Size(GF_Box * s)700 GF_Err hlit_Size(GF_Box *s)
701 {
702 	GF_Err e = gf_isom_box_get_size(s);
703 	if (e) return e;
704 	s->size += 4;
705 	return GF_OK;
706 }
707 
708 #endif /*GPAC_DISABLE_ISOM_WRITE*/
709 
hclr_New()710 GF_Box *hclr_New()
711 {
712 	ISOM_DECL_BOX_ALLOC(GF_TextHighlightColorBox, GF_ISOM_BOX_TYPE_HCLR);
713 	return (GF_Box *)tmp;
714 }
715 
hclr_del(GF_Box * s)716 void hclr_del(GF_Box *s)
717 {
718 	gf_free(s);
719 }
720 
hclr_Read(GF_Box * s,GF_BitStream * bs)721 GF_Err hclr_Read(GF_Box *s, GF_BitStream *bs)
722 {
723 	GF_TextHighlightColorBox*ptr = (GF_TextHighlightColorBox*)s;
724 	ptr->hil_color = gpp_read_rgba(bs);
725 	return GF_OK;
726 }
727 
728 #ifndef GPAC_DISABLE_ISOM_WRITE
hclr_Write(GF_Box * s,GF_BitStream * bs)729 GF_Err hclr_Write(GF_Box *s, GF_BitStream *bs)
730 {
731 	GF_Err e;
732 	GF_TextHighlightColorBox*ptr = (GF_TextHighlightColorBox*)s;
733 	e = gf_isom_box_write_header(s, bs);
734 	if (e) return e;
735 	gpp_write_rgba(bs, ptr->hil_color);
736 	return GF_OK;
737 }
738 
hclr_Size(GF_Box * s)739 GF_Err hclr_Size(GF_Box *s)
740 {
741 	GF_Err e = gf_isom_box_get_size(s);
742 	if (e) return e;
743 	s->size += 4;
744 	return GF_OK;
745 }
746 
747 #endif /*GPAC_DISABLE_ISOM_WRITE*/
748 
krok_New()749 GF_Box *krok_New()
750 {
751 	ISOM_DECL_BOX_ALLOC(GF_TextKaraokeBox, GF_ISOM_BOX_TYPE_KROK);
752 	return (GF_Box *)tmp;
753 }
754 
krok_del(GF_Box * s)755 void krok_del(GF_Box *s)
756 {
757 	GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s;
758 	if (ptr->records) gf_free(ptr->records);
759 	gf_free(ptr);
760 }
761 
krok_Read(GF_Box * s,GF_BitStream * bs)762 GF_Err krok_Read(GF_Box *s, GF_BitStream *bs)
763 {
764 	GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s;
765 
766 	ptr->highlight_starttime = gf_bs_read_u32(bs);
767 	ptr->nb_entries = gf_bs_read_u16(bs);
768 	if (ptr->nb_entries) {
769 		u32 i;
770 		ptr->records = (KaraokeRecord*)gf_malloc(sizeof(KaraokeRecord)*ptr->nb_entries);
771 		for (i = 0; i<ptr->nb_entries; i++) {
772 			ptr->records[i].highlight_endtime = gf_bs_read_u32(bs);
773 			ptr->records[i].start_charoffset = gf_bs_read_u16(bs);
774 			ptr->records[i].end_charoffset = gf_bs_read_u16(bs);
775 		}
776 	}
777 	return GF_OK;
778 }
779 
780 #ifndef GPAC_DISABLE_ISOM_WRITE
krok_Write(GF_Box * s,GF_BitStream * bs)781 GF_Err krok_Write(GF_Box *s, GF_BitStream *bs)
782 {
783 	GF_Err e;
784 	u32 i;
785 	GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s;
786 	e = gf_isom_box_write_header(s, bs);
787 	if (e) return e;
788 
789 	gf_bs_write_u32(bs, ptr->highlight_starttime);
790 	gf_bs_write_u16(bs, ptr->nb_entries);
791 	for (i = 0; i<ptr->nb_entries; i++) {
792 		gf_bs_write_u32(bs, ptr->records[i].highlight_endtime);
793 		gf_bs_write_u16(bs, ptr->records[i].start_charoffset);
794 		gf_bs_write_u16(bs, ptr->records[i].end_charoffset);
795 	}
796 	return GF_OK;
797 }
798 
krok_Size(GF_Box * s)799 GF_Err krok_Size(GF_Box *s)
800 {
801 	GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s;
802 	GF_Err e = gf_isom_box_get_size(s);
803 	if (e) return e;
804 	s->size += 6 * 8 * ptr->nb_entries;
805 	return GF_OK;
806 }
807 
808 #endif /*GPAC_DISABLE_ISOM_WRITE*/
809 
dlay_New()810 GF_Box *dlay_New()
811 {
812 	ISOM_DECL_BOX_ALLOC(GF_TextScrollDelayBox, GF_ISOM_BOX_TYPE_DLAY);
813 	return (GF_Box *)tmp;
814 }
815 
dlay_del(GF_Box * s)816 void dlay_del(GF_Box *s)
817 {
818 	gf_free(s);
819 }
820 
dlay_Read(GF_Box * s,GF_BitStream * bs)821 GF_Err dlay_Read(GF_Box *s, GF_BitStream *bs)
822 {
823 	GF_TextScrollDelayBox*ptr = (GF_TextScrollDelayBox*)s;
824 	ptr->scroll_delay = gf_bs_read_u32(bs);
825 	return GF_OK;
826 }
827 
828 #ifndef GPAC_DISABLE_ISOM_WRITE
dlay_Write(GF_Box * s,GF_BitStream * bs)829 GF_Err dlay_Write(GF_Box *s, GF_BitStream *bs)
830 {
831 	GF_Err e;
832 	GF_TextScrollDelayBox*ptr = (GF_TextScrollDelayBox*)s;
833 	e = gf_isom_box_write_header(s, bs);
834 	if (e) return e;
835 	gf_bs_write_u32(bs, ptr->scroll_delay);
836 	return GF_OK;
837 }
838 
dlay_Size(GF_Box * s)839 GF_Err dlay_Size(GF_Box *s)
840 {
841 	GF_Err e = gf_isom_box_get_size(s);
842 	if (e) return e;
843 	s->size += 4;
844 	return GF_OK;
845 }
846 
847 #endif /*GPAC_DISABLE_ISOM_WRITE*/
848 
href_New()849 GF_Box *href_New()
850 {
851 	ISOM_DECL_BOX_ALLOC(GF_TextHyperTextBox, GF_ISOM_BOX_TYPE_HREF);
852 	return (GF_Box *)tmp;
853 }
854 
href_del(GF_Box * s)855 void href_del(GF_Box *s)
856 {
857 	GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s;
858 	if (ptr->URL) gf_free(ptr->URL);
859 	if (ptr->URL_hint) gf_free(ptr->URL_hint);
860 	gf_free(ptr);
861 }
862 
href_Read(GF_Box * s,GF_BitStream * bs)863 GF_Err href_Read(GF_Box *s, GF_BitStream *bs)
864 {
865 	u32 len;
866 	GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s;
867 	ptr->startcharoffset = gf_bs_read_u16(bs);
868 	ptr->endcharoffset = gf_bs_read_u16(bs);
869 	len = gf_bs_read_u8(bs);
870 	if (len) {
871 		ptr->URL = (char *)gf_malloc(sizeof(char) * (len + 1));
872 		gf_bs_read_data(bs, ptr->URL, len);
873 		ptr->URL[len] = 0;
874 	}
875 	len = gf_bs_read_u8(bs);
876 	if (len) {
877 		ptr->URL_hint = (char *)gf_malloc(sizeof(char) * (len + 1));
878 		gf_bs_read_data(bs, ptr->URL_hint, len);
879 		ptr->URL_hint[len] = 0;
880 	}
881 	return GF_OK;
882 }
883 
884 #ifndef GPAC_DISABLE_ISOM_WRITE
href_Write(GF_Box * s,GF_BitStream * bs)885 GF_Err href_Write(GF_Box *s, GF_BitStream *bs)
886 {
887 	u32 len;
888 	GF_Err e;
889 	GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s;
890 	e = gf_isom_box_write_header(s, bs);
891 	if (e) return e;
892 
893 	gf_bs_write_u16(bs, ptr->startcharoffset);
894 	gf_bs_write_u16(bs, ptr->endcharoffset);
895 	if (ptr->URL) {
896 		len = (u32)strlen(ptr->URL);
897 		gf_bs_write_u8(bs, len);
898 		gf_bs_write_data(bs, ptr->URL, len);
899 	}
900 	else {
901 		gf_bs_write_u8(bs, 0);
902 	}
903 	if (ptr->URL_hint) {
904 		len = (u32)strlen(ptr->URL_hint);
905 		gf_bs_write_u8(bs, len);
906 		gf_bs_write_data(bs, ptr->URL_hint, len);
907 	}
908 	else {
909 		gf_bs_write_u8(bs, 0);
910 	}
911 	return GF_OK;
912 }
913 
href_Size(GF_Box * s)914 GF_Err href_Size(GF_Box *s)
915 {
916 	GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s;
917 	GF_Err e = gf_isom_box_get_size(s);
918 	if (e) return e;
919 	s->size += 6;
920 	if (ptr->URL) s->size += strlen(ptr->URL);
921 	if (ptr->URL_hint) s->size += strlen(ptr->URL_hint);
922 	return GF_OK;
923 }
924 
925 #endif /*GPAC_DISABLE_ISOM_WRITE*/
926 
927 
tbox_New()928 GF_Box *tbox_New()
929 {
930 	ISOM_DECL_BOX_ALLOC(GF_TextBoxBox, GF_ISOM_BOX_TYPE_TBOX);
931 	return (GF_Box *)tmp;
932 }
933 
tbox_del(GF_Box * s)934 void tbox_del(GF_Box *s)
935 {
936 	gf_free(s);
937 }
938 
tbox_Read(GF_Box * s,GF_BitStream * bs)939 GF_Err tbox_Read(GF_Box *s, GF_BitStream *bs)
940 {
941 	GF_TextBoxBox*ptr = (GF_TextBoxBox*)s;
942 	gpp_read_box(bs, &ptr->box);
943 	return GF_OK;
944 }
945 
946 #ifndef GPAC_DISABLE_ISOM_WRITE
tbox_Write(GF_Box * s,GF_BitStream * bs)947 GF_Err tbox_Write(GF_Box *s, GF_BitStream *bs)
948 {
949 	GF_Err e;
950 	GF_TextBoxBox*ptr = (GF_TextBoxBox*)s;
951 	e = gf_isom_box_write_header(s, bs);
952 	if (e) return e;
953 	gpp_write_box(bs, &ptr->box);
954 	return GF_OK;
955 }
956 
tbox_Size(GF_Box * s)957 GF_Err tbox_Size(GF_Box *s)
958 {
959 	GF_Err e = gf_isom_box_get_size(s);
960 	if (e) return e;
961 	s->size += 8;
962 	return GF_OK;
963 }
964 
965 #endif /*GPAC_DISABLE_ISOM_WRITE*/
966 
967 
blnk_New()968 GF_Box *blnk_New()
969 {
970 	ISOM_DECL_BOX_ALLOC(GF_TextBlinkBox, GF_ISOM_BOX_TYPE_BLNK);
971 	return (GF_Box *)tmp;
972 }
973 
blnk_del(GF_Box * s)974 void blnk_del(GF_Box *s)
975 {
976 	gf_free(s);
977 }
978 
blnk_Read(GF_Box * s,GF_BitStream * bs)979 GF_Err blnk_Read(GF_Box *s, GF_BitStream *bs)
980 {
981 	GF_TextBlinkBox*ptr = (GF_TextBlinkBox*)s;
982 	ptr->startcharoffset = gf_bs_read_u16(bs);
983 	ptr->endcharoffset = gf_bs_read_u16(bs);
984 	return GF_OK;
985 }
986 
987 #ifndef GPAC_DISABLE_ISOM_WRITE
blnk_Write(GF_Box * s,GF_BitStream * bs)988 GF_Err blnk_Write(GF_Box *s, GF_BitStream *bs)
989 {
990 	GF_Err e;
991 	GF_TextBlinkBox*ptr = (GF_TextBlinkBox*)s;
992 	e = gf_isom_box_write_header(s, bs);
993 	if (e) return e;
994 	gf_bs_write_u16(bs, ptr->startcharoffset);
995 	gf_bs_write_u16(bs, ptr->endcharoffset);
996 	return GF_OK;
997 }
998 
blnk_Size(GF_Box * s)999 GF_Err blnk_Size(GF_Box *s)
1000 {
1001 	GF_Err e = gf_isom_box_get_size(s);
1002 	if (e) return e;
1003 	s->size += 4;
1004 	return GF_OK;
1005 }
1006 
1007 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1008 
twrp_New()1009 GF_Box *twrp_New()
1010 {
1011 	ISOM_DECL_BOX_ALLOC(GF_TextWrapBox, GF_ISOM_BOX_TYPE_TWRP);
1012 	return (GF_Box *)tmp;
1013 }
1014 
twrp_del(GF_Box * s)1015 void twrp_del(GF_Box *s)
1016 {
1017 	gf_free(s);
1018 }
1019 
twrp_Read(GF_Box * s,GF_BitStream * bs)1020 GF_Err twrp_Read(GF_Box *s, GF_BitStream *bs)
1021 {
1022 	GF_TextWrapBox*ptr = (GF_TextWrapBox*)s;
1023 	ptr->wrap_flag = gf_bs_read_u8(bs);
1024 	return GF_OK;
1025 }
1026 
1027 #ifndef GPAC_DISABLE_ISOM_WRITE
twrp_Write(GF_Box * s,GF_BitStream * bs)1028 GF_Err twrp_Write(GF_Box *s, GF_BitStream *bs)
1029 {
1030 	GF_Err e;
1031 	GF_TextWrapBox*ptr = (GF_TextWrapBox*)s;
1032 	e = gf_isom_box_write_header(s, bs);
1033 	if (e) return e;
1034 	gf_bs_write_u8(bs, ptr->wrap_flag);
1035 	return GF_OK;
1036 }
twrp_Size(GF_Box * s)1037 GF_Err twrp_Size(GF_Box *s)
1038 {
1039 	GF_Err e = gf_isom_box_get_size(s);
1040 	if (e) return e;
1041 	s->size += 1;
1042 	return GF_OK;
1043 }
1044 
1045 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1046 
tsel_del(GF_Box * s)1047 void tsel_del(GF_Box *s)
1048 {
1049 	GF_TrackSelectionBox *ptr;
1050 	ptr = (GF_TrackSelectionBox *)s;
1051 	if (ptr == NULL) return;
1052 	if (ptr->attributeList) gf_free(ptr->attributeList);
1053 	gf_free(ptr);
1054 }
1055 
tsel_Read(GF_Box * s,GF_BitStream * bs)1056 GF_Err tsel_Read(GF_Box *s, GF_BitStream *bs)
1057 {
1058 	GF_Err e;
1059 	u32 i;
1060 	GF_TrackSelectionBox *ptr = (GF_TrackSelectionBox *)s;
1061 	e = gf_isom_full_box_read(s, bs);
1062 	if (e) return e;
1063 	ptr->switchGroup = gf_bs_read_u32(bs);
1064 	ptr->size -= 4;
1065 	if (ptr->size % 4) return GF_ISOM_INVALID_FILE;
1066 	ptr->attributeListCount = (u32)ptr->size / 4;
1067 	ptr->attributeList = gf_malloc(ptr->attributeListCount * sizeof(u32));
1068 	if (ptr->attributeList == NULL) return GF_OUT_OF_MEM;
1069 
1070 	for (i = 0; i< ptr->attributeListCount; i++) {
1071 		ptr->attributeList[i] = gf_bs_read_u32(bs);
1072 	}
1073 	return GF_OK;
1074 }
1075 
tsel_New()1076 GF_Box *tsel_New()
1077 {
1078 	ISOM_DECL_BOX_ALLOC(GF_TrackSelectionBox, GF_ISOM_BOX_TYPE_TSEL);
1079 	gf_isom_full_box_init((GF_Box *)tmp);
1080 	return (GF_Box *)tmp;
1081 }
1082 
1083 
1084 #ifndef GPAC_DISABLE_ISOM_WRITE
1085 
tsel_Write(GF_Box * s,GF_BitStream * bs)1086 GF_Err tsel_Write(GF_Box *s, GF_BitStream *bs)
1087 {
1088 	GF_Err e;
1089 	u32 i;
1090 	GF_TrackSelectionBox *ptr = (GF_TrackSelectionBox *)s;
1091 
1092 	e = gf_isom_full_box_write(s, bs);
1093 	if (e) return e;
1094 	gf_bs_write_u32(bs, ptr->switchGroup);
1095 
1096 	for (i = 0; i < ptr->attributeListCount; i++) {
1097 		gf_bs_write_u32(bs, ptr->attributeList[i]);
1098 	}
1099 
1100 	return GF_OK;
1101 }
1102 
tsel_Size(GF_Box * s)1103 GF_Err tsel_Size(GF_Box *s)
1104 {
1105 	GF_Err e;
1106 	GF_TrackSelectionBox *ptr = (GF_TrackSelectionBox *)s;
1107 	e = gf_isom_full_box_get_size(s);
1108 	if (e) return e;
1109 	ptr->size += 4 + (4 * ptr->attributeListCount);
1110 	return GF_OK;
1111 }
1112 
1113 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1114 
1115 
dimC_New()1116 GF_Box *dimC_New()
1117 {
1118 	ISOM_DECL_BOX_ALLOC(GF_DIMSSceneConfigBox, GF_ISOM_BOX_TYPE_DIMC);
1119 	gf_isom_full_box_init((GF_Box *)tmp);
1120 	return (GF_Box *)tmp;
1121 }
dimC_del(GF_Box * s)1122 void dimC_del(GF_Box *s)
1123 {
1124 	GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s;
1125 	if (p->contentEncoding) gf_free(p->contentEncoding);
1126 	if (p->textEncoding) gf_free(p->textEncoding);
1127 	gf_free(p);
1128 }
1129 
dimC_Read(GF_Box * s,GF_BitStream * bs)1130 GF_Err dimC_Read(GF_Box *s, GF_BitStream *bs)
1131 {
1132 	char str[1024];
1133 	u32 i;
1134 	GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s;
1135 	GF_Err e = gf_isom_full_box_read(s, bs);
1136 	if (e) return e;
1137 
1138 	p->profile = gf_bs_read_u8(bs);
1139 	p->level = gf_bs_read_u8(bs);
1140 	p->pathComponents = gf_bs_read_int(bs, 4);
1141 	p->fullRequestHost = gf_bs_read_int(bs, 1);
1142 	p->streamType = gf_bs_read_int(bs, 1);
1143 	p->containsRedundant = gf_bs_read_int(bs, 2);
1144 	s->size -= 3;
1145 
1146 	i = 0;
1147 	str[0] = 0;
1148 	while (1) {
1149 		str[i] = gf_bs_read_u8(bs);
1150 		if (!str[i]) break;
1151 		i++;
1152 	}
1153 	if (s->size < i) return GF_ISOM_INVALID_FILE;
1154 	s->size -= i;
1155 	p->textEncoding = gf_strdup(str);
1156 
1157 	i = 0;
1158 	str[0] = 0;
1159 	while (1) {
1160 		str[i] = gf_bs_read_u8(bs);
1161 		if (!str[i]) break;
1162 		i++;
1163 	}
1164 	if (s->size < i) return GF_ISOM_INVALID_FILE;
1165 	s->size -= i;
1166 	p->contentEncoding = gf_strdup(str);
1167 	return GF_OK;
1168 }
1169 
1170 #ifndef GPAC_DISABLE_ISOM_WRITE
dimC_Write(GF_Box * s,GF_BitStream * bs)1171 GF_Err dimC_Write(GF_Box *s, GF_BitStream *bs)
1172 {
1173 	GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s;
1174 	GF_Err e = gf_isom_full_box_write(s, bs);
1175 	if (e) return e;
1176 	gf_bs_write_u8(bs, p->profile);
1177 	gf_bs_write_u8(bs, p->level);
1178 	gf_bs_write_int(bs, p->pathComponents, 4);
1179 	gf_bs_write_int(bs, p->fullRequestHost, 1);
1180 	gf_bs_write_int(bs, p->streamType, 1);
1181 	gf_bs_write_int(bs, p->containsRedundant, 2);
1182 	gf_bs_write_data(bs, p->textEncoding, (u32)strlen(p->textEncoding) + 1);
1183 	gf_bs_write_data(bs, p->contentEncoding, (u32)strlen(p->contentEncoding) + 1);
1184 	return GF_OK;
1185 }
dimC_Size(GF_Box * s)1186 GF_Err dimC_Size(GF_Box *s)
1187 {
1188 	GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s;
1189 	GF_Err e = gf_isom_full_box_get_size(s);
1190 	if (e) return e;
1191 	s->size += 3 + 1 + strlen(p->textEncoding) + 1 + strlen(p->contentEncoding);
1192 	return GF_OK;
1193 }
1194 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1195 
1196 
1197 
diST_New()1198 GF_Box *diST_New()
1199 {
1200 	ISOM_DECL_BOX_ALLOC(GF_DIMSScriptTypesBox, GF_ISOM_BOX_TYPE_DIST);
1201 	return (GF_Box *)tmp;
1202 }
diST_del(GF_Box * s)1203 void diST_del(GF_Box *s)
1204 {
1205 	GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s;
1206 	if (p->content_script_types) gf_free(p->content_script_types);
1207 	gf_free(p);
1208 }
1209 
diST_Read(GF_Box * s,GF_BitStream * bs)1210 GF_Err diST_Read(GF_Box *s, GF_BitStream *bs)
1211 {
1212 	u32 i;
1213 	char str[1024];
1214 	GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s;
1215 
1216 	i = 0;
1217 	str[0] = 0;
1218 	while (1) {
1219 		str[i] = gf_bs_read_u8(bs);
1220 		if (!str[i]) break;
1221 		i++;
1222 	}
1223 	if (s->size < i) return GF_ISOM_INVALID_FILE;
1224 	s->size -= i;
1225 	p->content_script_types = gf_strdup(str);
1226 	return GF_OK;
1227 }
1228 
1229 #ifndef GPAC_DISABLE_ISOM_WRITE
diST_Write(GF_Box * s,GF_BitStream * bs)1230 GF_Err diST_Write(GF_Box *s, GF_BitStream *bs)
1231 {
1232 	GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s;
1233 	GF_Err e = gf_isom_box_write_header(s, bs);
1234 	if (e) return e;
1235 	if (p->content_script_types)
1236 		gf_bs_write_data(bs, p->content_script_types, (u32)strlen(p->content_script_types) + 1);
1237 	else
1238 		gf_bs_write_u8(bs, 0);
1239 	return GF_OK;
1240 }
diST_Size(GF_Box * s)1241 GF_Err diST_Size(GF_Box *s)
1242 {
1243 	GF_Err e = gf_isom_box_get_size(s);
1244 	GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s;
1245 	if (e) return e;
1246 	s->size += p->content_script_types ? (strlen(p->content_script_types) + 1) : 1;
1247 	return GF_OK;
1248 }
1249 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1250 
1251 
dims_New()1252 GF_Box *dims_New()
1253 {
1254 	ISOM_DECL_BOX_ALLOC(GF_DIMSSampleEntryBox, GF_ISOM_BOX_TYPE_DIMS);
1255 	return (GF_Box*)tmp;
1256 }
dims_del(GF_Box * s)1257 void dims_del(GF_Box *s)
1258 {
1259 	GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s;
1260 	gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
1261 
1262 	if (p->config) gf_isom_box_del((GF_Box *)p->config);
1263 	if (p->scripts) gf_isom_box_del((GF_Box *)p->scripts);
1264 	gf_free(p);
1265 }
1266 
dims_AddBox(GF_Box * s,GF_Box * a)1267 static GF_Err dims_AddBox(GF_Box *s, GF_Box *a)
1268 {
1269 	GF_DIMSSampleEntryBox *ptr = (GF_DIMSSampleEntryBox  *)s;
1270 	switch (a->type) {
1271 	case GF_ISOM_BOX_TYPE_DIMC:
1272 		if (ptr->config) ERROR_ON_DUPLICATED_BOX(a, ptr)
1273 			ptr->config = (GF_DIMSSceneConfigBox*)a;
1274 		break;
1275 	case GF_ISOM_BOX_TYPE_DIST:
1276 		if (ptr->scripts) ERROR_ON_DUPLICATED_BOX(a, ptr)
1277 			ptr->scripts = (GF_DIMSScriptTypesBox*)a;
1278 		break;
1279 	case GF_ISOM_BOX_TYPE_SINF:
1280 		gf_list_add(ptr->protections, a);
1281 		break;
1282 	default:
1283 		return gf_isom_box_add_default(s, a);
1284 	}
1285 	return GF_OK;
1286 }
dims_Read(GF_Box * s,GF_BitStream * bs)1287 GF_Err dims_Read(GF_Box *s, GF_BitStream *bs)
1288 {
1289 	GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s;
1290 	gf_bs_read_data(bs, p->reserved, 6);
1291 	p->dataReferenceIndex = gf_bs_read_u16(bs);
1292 	p->size -= 8;
1293 	return gf_isom_read_box_list(s, bs, dims_AddBox);
1294 }
1295 
1296 #ifndef GPAC_DISABLE_ISOM_WRITE
dims_Write(GF_Box * s,GF_BitStream * bs)1297 GF_Err dims_Write(GF_Box *s, GF_BitStream *bs)
1298 {
1299 	GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s;
1300 	GF_Err e = gf_isom_box_write_header(s, bs);
1301 	if (e) return e;
1302 	gf_bs_write_data(bs, p->reserved, 6);
1303 	gf_bs_write_u16(bs, p->dataReferenceIndex);
1304 	if (p->config) {
1305 		e = gf_isom_box_write((GF_Box *)p->config, bs);
1306 		if (e) return e;
1307 	}
1308 	if (p->scripts) {
1309 		e = gf_isom_box_write((GF_Box *)p->scripts, bs);
1310 		if (e) return e;
1311 	}
1312 	return gf_isom_box_array_write(s, p->protections, bs);
1313 }
1314 
dims_Size(GF_Box * s)1315 GF_Err dims_Size(GF_Box *s)
1316 {
1317 	GF_Err e = gf_isom_box_get_size(s);
1318 	GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s;
1319 	if (e) return e;
1320 	s->size += 8;
1321 
1322 	if (p->config) {
1323 		e = gf_isom_box_size((GF_Box *)p->config);
1324 		if (e) return e;
1325 		p->size += p->config->size;
1326 	}
1327 	if (p->scripts) {
1328 		e = gf_isom_box_size((GF_Box *)p->scripts);
1329 		if (e) return e;
1330 		p->size += p->scripts->size;
1331 	}
1332 	return gf_isom_box_array_size(s, p->protections);
1333 }
1334 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1335 
1336 #endif /*GPAC_DISABLE_ISOM*/
1337