1 /*
2 * GPAC - Multimedia Framework C SDK
3 *
4 * Authors: Cyril Concolato / Jean Le Feuvre
5 * Copyright (c) Telecom ParisTech 2005-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
meta_New()30 GF_Box *meta_New()
31 {
32 ISOM_DECL_BOX_ALLOC(GF_MetaBox, GF_ISOM_BOX_TYPE_META);
33 gf_isom_full_box_init((GF_Box *)tmp);
34 tmp->other_boxes = gf_list_new();
35 return (GF_Box *)tmp;
36 }
37
meta_del(GF_Box * s)38 void meta_del(GF_Box *s)
39 {
40 GF_MetaBox *ptr = (GF_MetaBox *)s;
41 if (ptr == NULL) return;
42 gf_isom_box_del((GF_Box *)ptr->handler);
43 if (ptr->primary_resource) gf_isom_box_del((GF_Box *)ptr->primary_resource);
44 if (ptr->file_locations) gf_isom_box_del((GF_Box *)ptr->file_locations);
45 if (ptr->item_locations) gf_isom_box_del((GF_Box *)ptr->item_locations);
46 if (ptr->protections) gf_isom_box_del((GF_Box *)ptr->protections);
47 if (ptr->item_infos) gf_isom_box_del((GF_Box *)ptr->item_infos);
48 if (ptr->IPMP_control) gf_isom_box_del((GF_Box *)ptr->IPMP_control);
49 if (ptr->item_refs) gf_isom_box_del((GF_Box *)ptr->item_refs);
50 if (ptr->item_props) gf_isom_box_del((GF_Box *)ptr->item_props);
51 gf_free(ptr);
52 }
53
meta_AddBox(GF_Box * s,GF_Box * a)54 GF_Err meta_AddBox(GF_Box *s, GF_Box *a)
55 {
56 GF_MetaBox *ptr = (GF_MetaBox *)s;
57 switch (a->type) {
58 case GF_ISOM_BOX_TYPE_HDLR:
59 if (ptr->handler) return GF_ISOM_INVALID_FILE;
60 ptr->handler = (GF_HandlerBox*)a;
61 break;
62 case GF_ISOM_BOX_TYPE_PITM:
63 if (ptr->primary_resource) return GF_ISOM_INVALID_FILE;
64 ptr->primary_resource = (GF_PrimaryItemBox*)a;
65 break;
66 case GF_ISOM_BOX_TYPE_DINF:
67 if (ptr->file_locations) return GF_ISOM_INVALID_FILE;
68 ptr->file_locations = (GF_DataInformationBox*)a;
69 break;
70 case GF_ISOM_BOX_TYPE_ILOC:
71 if (ptr->item_locations) return GF_ISOM_INVALID_FILE;
72 ptr->item_locations = (GF_ItemLocationBox*)a;
73 break;
74 case GF_ISOM_BOX_TYPE_IPRO:
75 if (ptr->protections) return GF_ISOM_INVALID_FILE;
76 ptr->protections = (GF_ItemProtectionBox*)a;
77 break;
78 case GF_ISOM_BOX_TYPE_IINF:
79 if (ptr->item_infos) return GF_ISOM_INVALID_FILE;
80 ptr->item_infos = (GF_ItemInfoBox*)a;
81 break;
82 case GF_ISOM_BOX_TYPE_IREF:
83 if (ptr->item_refs) return GF_ISOM_INVALID_FILE;
84 ptr->item_refs = (GF_ItemReferenceBox*)a;
85 break;
86 case GF_ISOM_BOX_TYPE_IPRP:
87 if (ptr->item_props) return GF_ISOM_INVALID_FILE;
88 ptr->item_props = (GF_ItemPropertiesBox*)a;
89 break;
90 //case ???: ptr->IPMP_control = (???*)a; break;
91 case GF_ISOM_BOX_TYPE_XML:
92 case GF_ISOM_BOX_TYPE_BXML:
93 case GF_ISOM_BOX_TYPE_ILST:
94 default:
95 return gf_isom_box_add_default(s, a);
96 }
97 return GF_OK;
98 }
99
meta_Read(GF_Box * s,GF_BitStream * bs)100 GF_Err meta_Read(GF_Box *s, GF_BitStream *bs)
101 {
102 u32 next_size = gf_bs_peek_bits(bs, 32, 4);
103 GF_Err e;
104 /*try to hack around QT files which don't use a full box for meta*/
105 if (next_size<s->size) {
106 e = gf_isom_full_box_read(s, bs);
107 if (e) return e;
108 }
109 return gf_isom_read_box_list(s, bs, meta_AddBox);
110 }
111
112 #ifndef GPAC_DISABLE_ISOM_WRITE
meta_Write(GF_Box * s,GF_BitStream * bs)113 GF_Err meta_Write(GF_Box *s, GF_BitStream *bs)
114 {
115 GF_Err e;
116 GF_MetaBox *ptr = (GF_MetaBox *)s;
117 if (!s) return GF_BAD_PARAM;
118 e = gf_isom_full_box_write(s, bs);
119 if (e) return e;
120 if (ptr->handler) {
121 e = gf_isom_box_write((GF_Box *)ptr->handler, bs);
122 if (e) return e;
123 }
124 if (ptr->primary_resource) {
125 e = gf_isom_box_write((GF_Box *)ptr->primary_resource, bs);
126 if (e) return e;
127 }
128 if (ptr->file_locations) {
129 e = gf_isom_box_write((GF_Box *)ptr->file_locations, bs);
130 if (e) return e;
131 }
132 if (ptr->item_locations) {
133 e = gf_isom_box_write((GF_Box *)ptr->item_locations, bs);
134 if (e) return e;
135 }
136 if (ptr->protections) {
137 e = gf_isom_box_write((GF_Box *)ptr->protections, bs);
138 if (e) return e;
139 }
140 if (ptr->item_infos) {
141 e = gf_isom_box_write((GF_Box *)ptr->item_infos, bs);
142 if (e) return e;
143 }
144 if (ptr->IPMP_control) {
145 e = gf_isom_box_write((GF_Box *)ptr->IPMP_control, bs);
146 if (e) return e;
147 }
148 if (ptr->item_refs) {
149 e = gf_isom_box_write((GF_Box *)ptr->item_refs, bs);
150 if (e) return e;
151 }
152 if (ptr->item_props) {
153 e = gf_isom_box_write((GF_Box *)ptr->item_props, bs);
154 if (e) return e;
155 }
156 return GF_OK;
157 }
158
meta_Size(GF_Box * s)159 GF_Err meta_Size(GF_Box *s)
160 {
161 GF_Err e;
162 GF_MetaBox *ptr = (GF_MetaBox *)s;
163 if (!s) return GF_BAD_PARAM;
164 e = gf_isom_full_box_get_size(s);
165 if (e) return e;
166 if (ptr->handler) {
167 e = gf_isom_box_size((GF_Box *)ptr->handler);
168 if (e) return e;
169 ptr->size += ptr->handler->size;
170 }
171 if (ptr->primary_resource) {
172 e = gf_isom_box_size((GF_Box *)ptr->primary_resource);
173 if (e) return e;
174 ptr->size += ptr->primary_resource->size;
175 }
176 if (ptr->file_locations) {
177 e = gf_isom_box_size((GF_Box *)ptr->file_locations);
178 if (e) return e;
179 ptr->size += ptr->file_locations->size;
180 }
181 if (ptr->item_locations) {
182 e = gf_isom_box_size((GF_Box *)ptr->item_locations);
183 if (e) return e;
184 ptr->size += ptr->item_locations->size;
185 }
186 if (ptr->protections) {
187 e = gf_isom_box_size((GF_Box *)ptr->protections);
188 if (e) return e;
189 ptr->size += ptr->protections->size;
190 }
191 if (ptr->item_infos) {
192 e = gf_isom_box_size((GF_Box *)ptr->item_infos);
193 if (e) return e;
194 ptr->size += ptr->item_infos->size;
195 }
196 if (ptr->IPMP_control) {
197 e = gf_isom_box_size((GF_Box *)ptr->IPMP_control);
198 if (e) return e;
199 ptr->size += ptr->IPMP_control->size;
200 }
201 if (ptr->item_refs) {
202 e = gf_isom_box_size((GF_Box *)ptr->item_refs);
203 if (e) return e;
204 ptr->size += ptr->item_refs->size;
205 }
206 if (ptr->item_props) {
207 e = gf_isom_box_size((GF_Box *)ptr->item_props);
208 if (e) return e;
209 ptr->size += ptr->item_props->size;
210 }
211 return GF_OK;
212 }
213 #endif /*GPAC_DISABLE_ISOM_WRITE*/
214
xml_New()215 GF_Box *xml_New()
216 {
217 ISOM_DECL_BOX_ALLOC(GF_XMLBox, GF_ISOM_BOX_TYPE_XML);
218 gf_isom_full_box_init((GF_Box *)tmp);
219 return (GF_Box *)tmp;
220 }
221
xml_del(GF_Box * s)222 void xml_del(GF_Box *s)
223 {
224 GF_XMLBox *ptr = (GF_XMLBox *)s;
225 if (ptr == NULL) return;
226 if (ptr->xml_length && ptr->xml) gf_free(ptr->xml);
227 gf_free(ptr);
228 }
229
xml_Read(GF_Box * s,GF_BitStream * bs)230 GF_Err xml_Read(GF_Box *s, GF_BitStream *bs)
231 {
232 GF_Err e;
233 GF_XMLBox *ptr = (GF_XMLBox *)s;
234 if (ptr == NULL) return GF_BAD_PARAM;
235 e = gf_isom_full_box_read(s, bs);
236 if (e) return e;
237 ptr->xml_length = (u32)(ptr->size);
238 ptr->xml = (char *)gf_malloc(sizeof(char)*ptr->xml_length);
239 if (!ptr->xml) return GF_OUT_OF_MEM;
240 gf_bs_read_data(bs, ptr->xml, ptr->xml_length);
241 return GF_OK;
242 }
243
244 #ifndef GPAC_DISABLE_ISOM_WRITE
xml_Write(GF_Box * s,GF_BitStream * bs)245 GF_Err xml_Write(GF_Box *s, GF_BitStream *bs)
246 {
247 GF_Err e;
248 GF_XMLBox *ptr = (GF_XMLBox *)s;
249 if (!s) return GF_BAD_PARAM;
250 e = gf_isom_full_box_write(s, bs);
251 if (e) return e;
252 if (ptr->xml_length) gf_bs_write_data(bs, ptr->xml, ptr->xml_length);
253 return GF_OK;
254 }
255
xml_Size(GF_Box * s)256 GF_Err xml_Size(GF_Box *s)
257 {
258 GF_Err e;
259 GF_XMLBox *ptr = (GF_XMLBox *)s;
260 if (!s) return GF_BAD_PARAM;
261 e = gf_isom_full_box_get_size(s);
262 if (e) return e;
263 ptr->size += ptr->xml_length;
264 return GF_OK;
265 }
266 #endif /*GPAC_DISABLE_ISOM_WRITE*/
267
bxml_New()268 GF_Box *bxml_New()
269 {
270 ISOM_DECL_BOX_ALLOC(GF_BinaryXMLBox, GF_ISOM_BOX_TYPE_BXML);
271 gf_isom_full_box_init((GF_Box *)tmp);
272 return (GF_Box *)tmp;
273 }
274
bxml_del(GF_Box * s)275 void bxml_del(GF_Box *s)
276 {
277 GF_BinaryXMLBox *ptr = (GF_BinaryXMLBox *)s;
278 if (ptr == NULL) return;
279 if (ptr->data_length && ptr->data) gf_free(ptr->data);
280 gf_free(ptr);
281 }
282
bxml_Read(GF_Box * s,GF_BitStream * bs)283 GF_Err bxml_Read(GF_Box *s, GF_BitStream *bs)
284 {
285 GF_Err e;
286 GF_BinaryXMLBox *ptr = (GF_BinaryXMLBox *)s;
287 e = gf_isom_full_box_read(s, bs);
288 if (e) return e;
289 ptr->data_length = (u32)(ptr->size);
290 ptr->data = (char*)gf_malloc(sizeof(char)*ptr->data_length);
291 if (!ptr->data) return GF_OUT_OF_MEM;
292 gf_bs_read_data(bs, ptr->data, ptr->data_length);
293 return GF_OK;
294 }
295
296 #ifndef GPAC_DISABLE_ISOM_WRITE
bxml_Write(GF_Box * s,GF_BitStream * bs)297 GF_Err bxml_Write(GF_Box *s, GF_BitStream *bs)
298 {
299 GF_Err e;
300 GF_BinaryXMLBox *ptr = (GF_BinaryXMLBox *)s;
301 if (!s) return GF_BAD_PARAM;
302 e = gf_isom_full_box_write(s, bs);
303 if (e) return e;
304 if (ptr->data_length) gf_bs_write_data(bs, ptr->data, ptr->data_length);
305 return GF_OK;
306 }
307
bxml_Size(GF_Box * s)308 GF_Err bxml_Size(GF_Box *s)
309 {
310 GF_Err e;
311 GF_BinaryXMLBox *ptr = (GF_BinaryXMLBox *)s;
312 if (!s) return GF_BAD_PARAM;
313 e = gf_isom_full_box_get_size(s);
314 if (e) return e;
315 ptr->size += ptr->data_length;
316 return GF_OK;
317 }
318 #endif /*GPAC_DISABLE_ISOM_WRITE*/
319
iloc_New()320 GF_Box *iloc_New()
321 {
322 ISOM_DECL_BOX_ALLOC(GF_ItemLocationBox, GF_ISOM_BOX_TYPE_ILOC);
323 gf_isom_full_box_init((GF_Box *)tmp);
324 tmp->location_entries = gf_list_new();
325 return (GF_Box *)tmp;
326 }
327
iloc_entry_del(GF_ItemLocationEntry * location)328 void iloc_entry_del(GF_ItemLocationEntry *location)
329 {
330 u32 j, extent_count;
331 extent_count = gf_list_count(location->extent_entries);
332 for (j = 0; j < extent_count; j++) {
333 GF_ItemExtentEntry *extent = (GF_ItemExtentEntry *)gf_list_get(location->extent_entries, j);
334 gf_free(extent);
335 }
336 gf_list_del(location->extent_entries);
337 gf_free(location);
338 }
339
iloc_del(GF_Box * s)340 void iloc_del(GF_Box *s)
341 {
342 u32 i, item_count;
343 GF_ItemLocationBox *ptr = (GF_ItemLocationBox *)s;
344 if (ptr == NULL) return;
345 item_count = gf_list_count(ptr->location_entries);
346 for (i = 0; i < item_count; i++) {
347 GF_ItemLocationEntry *location = (GF_ItemLocationEntry *)gf_list_get(ptr->location_entries, i);
348 iloc_entry_del(location);
349 }
350 gf_list_del(ptr->location_entries);
351 gf_free(ptr);
352 }
353
iloc_Read(GF_Box * s,GF_BitStream * bs)354 GF_Err iloc_Read(GF_Box *s, GF_BitStream *bs)
355 {
356 GF_Err e;
357 u32 item_count, extent_count, i, j;
358 GF_ItemLocationBox *ptr = (GF_ItemLocationBox *)s;
359 e = gf_isom_full_box_read(s, bs);
360 if (e) return e;
361 ptr->offset_size = gf_bs_read_int(bs, 4);
362 ptr->length_size = gf_bs_read_int(bs, 4);
363 ptr->base_offset_size = gf_bs_read_int(bs, 4);
364 if (ptr->version == 1 || ptr->version == 2) {
365 ptr->index_size = gf_bs_read_int(bs, 4);
366 }
367 else {
368 gf_bs_read_int(bs, 4);
369 }
370 if (ptr->version < 2) {
371 item_count = gf_bs_read_u16(bs);
372 }
373 else {
374 item_count = gf_bs_read_u32(bs);
375 }
376 for (i = 0; i < item_count; i++) {
377 GF_ItemLocationEntry *location_entry = (GF_ItemLocationEntry *)gf_malloc(sizeof(GF_ItemLocationEntry));
378 gf_list_add(ptr->location_entries, location_entry);
379 if (ptr->version < 2) {
380 location_entry->item_ID = gf_bs_read_u16(bs);
381 }
382 else {
383 location_entry->item_ID = gf_bs_read_u32(bs);
384 }
385 if (ptr->version == 1 || ptr->version == 2) {
386 location_entry->construction_method = gf_bs_read_u16(bs);
387 }
388 else {
389 location_entry->construction_method = 0;
390 }
391 location_entry->data_reference_index = gf_bs_read_u16(bs);
392 location_entry->base_offset = gf_bs_read_int(bs, 8 * ptr->base_offset_size);
393 #ifndef GPAC_DISABLE_ISOM_WRITE
394 location_entry->original_base_offset = location_entry->base_offset;
395 #endif
396
397 extent_count = gf_bs_read_u16(bs);
398 location_entry->extent_entries = gf_list_new();
399 for (j = 0; j < extent_count; j++) {
400 GF_ItemExtentEntry *extent_entry = (GF_ItemExtentEntry *)gf_malloc(sizeof(GF_ItemExtentEntry));
401 gf_list_add(location_entry->extent_entries, extent_entry);
402 if ((ptr->version == 1 || ptr->version == 2) && ptr->index_size > 0) {
403 extent_entry->extent_index = gf_bs_read_int(bs, 8 * ptr->index_size);;
404 }
405 else {
406 extent_entry->extent_index = 0;
407 }
408 extent_entry->extent_offset = gf_bs_read_int(bs, 8 * ptr->offset_size);
409 extent_entry->extent_length = gf_bs_read_int(bs, 8 * ptr->length_size);
410 #ifndef GPAC_DISABLE_ISOM_WRITE
411 extent_entry->original_extent_offset = extent_entry->extent_offset;
412 #endif
413 }
414 }
415 return GF_OK;
416 }
417
418 #ifndef GPAC_DISABLE_ISOM_WRITE
iloc_Write(GF_Box * s,GF_BitStream * bs)419 GF_Err iloc_Write(GF_Box *s, GF_BitStream *bs)
420 {
421 GF_Err e;
422 u32 i, j, item_count, extent_count;
423 GF_ItemLocationBox *ptr = (GF_ItemLocationBox *)s;
424 if (!s) return GF_BAD_PARAM;
425 e = gf_isom_full_box_write(s, bs);
426 if (e) return e;
427 gf_bs_write_int(bs, ptr->offset_size, 4);
428 gf_bs_write_int(bs, ptr->length_size, 4);
429 gf_bs_write_int(bs, ptr->base_offset_size, 4);
430 gf_bs_write_int(bs, ptr->index_size, 4);
431 item_count = gf_list_count(ptr->location_entries);
432 if (ptr->version < 2) {
433 gf_bs_write_u16(bs, item_count);
434 }
435 else {
436 gf_bs_write_u32(bs, item_count);
437 }
438 for (i = 0; i < item_count; i++) {
439 GF_ItemLocationEntry *location = (GF_ItemLocationEntry *)gf_list_get(ptr->location_entries, i);
440 if (ptr->version < 2) {
441 gf_bs_write_u16(bs, location->item_ID);
442 }
443 else {
444 gf_bs_write_u32(bs, location->item_ID);
445 }
446 if (ptr->version == 1 || ptr->version == 2) {
447 gf_bs_write_u16(bs, location->construction_method);
448 }
449 gf_bs_write_u16(bs, location->data_reference_index);
450 gf_bs_write_long_int(bs, location->base_offset, 8 * ptr->base_offset_size);
451 extent_count = gf_list_count(location->extent_entries);
452 gf_bs_write_u16(bs, extent_count);
453 for (j = 0; j<extent_count; j++) {
454 GF_ItemExtentEntry *extent = (GF_ItemExtentEntry *)gf_list_get(location->extent_entries, j);
455 if ((ptr->version == 1 || ptr->version == 2) && ptr->index_size > 0) {
456 gf_bs_write_long_int(bs, extent->extent_index, 8 * ptr->index_size);
457 }
458 gf_bs_write_long_int(bs, extent->extent_offset, 8 * ptr->offset_size);
459 gf_bs_write_long_int(bs, extent->extent_length, 8 * ptr->length_size);
460 }
461 }
462 return GF_OK;
463 }
464
iloc_Size(GF_Box * s)465 GF_Err iloc_Size(GF_Box *s)
466 {
467 GF_Err e;
468 u32 i, item_count, extent_count;
469 GF_ItemLocationBox *ptr = (GF_ItemLocationBox *)s;
470 if (!s) return GF_BAD_PARAM;
471 e = gf_isom_full_box_get_size(s);
472 if (e) return e;
473 if (ptr->index_size) {
474 ptr->version = 1;
475 }
476 item_count = gf_list_count(ptr->location_entries);
477 for (i = 0; i < item_count; i++) {
478 GF_ItemLocationEntry *location = (GF_ItemLocationEntry *)gf_list_get(ptr->location_entries, i);
479 if (location->construction_method) {
480 ptr->version = 1;
481 }
482 if (location->item_ID > 0xFFFF) {
483 ptr->version = 2;
484 }
485 }
486 ptr->size += 4;
487 if (ptr->version == 2) {
488 ptr->size += 2; // 32 bits item count instead of 16 bits
489 }
490 for (i = 0; i < item_count; i++) {
491 GF_ItemLocationEntry *location = (GF_ItemLocationEntry *)gf_list_get(ptr->location_entries, i);
492 extent_count = gf_list_count(location->extent_entries);
493 ptr->size += 6 + ptr->base_offset_size + extent_count*(ptr->offset_size + ptr->length_size);
494 if (ptr->version == 2) {
495 ptr->size += 2; //32 bits item ID instead of 16 bits
496 }
497 if (ptr->version == 1 || ptr->version == 2) {
498 ptr->size += 2; // construction_method
499 ptr->size += extent_count*ptr->index_size;
500 }
501 }
502 return GF_OK;
503 }
504 #endif /*GPAC_DISABLE_ISOM_WRITE*/
505
pitm_New()506 GF_Box *pitm_New()
507 {
508 ISOM_DECL_BOX_ALLOC(GF_PrimaryItemBox, GF_ISOM_BOX_TYPE_PITM);
509 gf_isom_full_box_init((GF_Box *)tmp);
510 return (GF_Box *)tmp;
511 }
512
pitm_del(GF_Box * s)513 void pitm_del(GF_Box *s)
514 {
515 GF_PrimaryItemBox *ptr = (GF_PrimaryItemBox *)s;
516 if (ptr == NULL) return;
517 gf_free(ptr);
518 }
519
pitm_Read(GF_Box * s,GF_BitStream * bs)520 GF_Err pitm_Read(GF_Box *s, GF_BitStream *bs)
521 {
522 GF_Err e;
523 GF_PrimaryItemBox *ptr = (GF_PrimaryItemBox *)s;
524 e = gf_isom_full_box_read(s, bs);
525 if (e) return e;
526 ptr->item_ID = gf_bs_read_u16(bs);
527 return GF_OK;
528 }
529
530 #ifndef GPAC_DISABLE_ISOM_WRITE
pitm_Write(GF_Box * s,GF_BitStream * bs)531 GF_Err pitm_Write(GF_Box *s, GF_BitStream *bs)
532 {
533 GF_Err e;
534 GF_PrimaryItemBox *ptr = (GF_PrimaryItemBox *)s;
535 if (!s) return GF_BAD_PARAM;
536 e = gf_isom_full_box_write(s, bs);
537 if (e) return e;
538 gf_bs_write_u16(bs, ptr->item_ID);
539 return GF_OK;
540 }
541
pitm_Size(GF_Box * s)542 GF_Err pitm_Size(GF_Box *s)
543 {
544 GF_Err e;
545 GF_ItemLocationBox *ptr = (GF_ItemLocationBox *)s;
546 if (!s) return GF_BAD_PARAM;
547 e = gf_isom_full_box_get_size(s);
548 if (e) return e;
549 ptr->size += 2;
550 return GF_OK;
551 }
552 #endif /*GPAC_DISABLE_ISOM_WRITE*/
553
ipro_New()554 GF_Box *ipro_New()
555 {
556 ISOM_DECL_BOX_ALLOC(GF_ItemProtectionBox, GF_ISOM_BOX_TYPE_IPRO);
557 gf_isom_full_box_init((GF_Box *)tmp);
558 tmp->protection_information = gf_list_new();
559 return (GF_Box *)tmp;
560 }
561
ipro_del(GF_Box * s)562 void ipro_del(GF_Box *s)
563 {
564 u32 count, i;
565 GF_ItemProtectionBox *ptr = (GF_ItemProtectionBox *)s;
566 if (ptr == NULL) return;
567 count = gf_list_count(ptr->protection_information);
568 for (i = 0; i < count; i++) {
569 GF_Box *a = (GF_Box *)gf_list_get(ptr->protection_information, i);
570 gf_isom_box_del(a);
571 }
572 gf_list_del(ptr->protection_information);
573 gf_free(ptr);
574 }
575
ipro_AddBox(GF_Box * s,GF_Box * a)576 GF_Err ipro_AddBox(GF_Box *s, GF_Box *a)
577 {
578 GF_ItemProtectionBox *ptr = (GF_ItemProtectionBox *)s;
579 if (a->type == GF_ISOM_BOX_TYPE_SINF)
580 return gf_list_add(ptr->protection_information, a);
581 else
582 return gf_isom_box_add_default(s, a);
583 }
ipro_Read(GF_Box * s,GF_BitStream * bs)584 GF_Err ipro_Read(GF_Box *s, GF_BitStream *bs)
585 {
586 GF_Err e;
587 e = gf_isom_full_box_read(s, bs);
588 if (e) return e;
589 return gf_isom_read_box_list(s, bs, ipro_AddBox);
590 }
591
592 #ifndef GPAC_DISABLE_ISOM_WRITE
ipro_Write(GF_Box * s,GF_BitStream * bs)593 GF_Err ipro_Write(GF_Box *s, GF_BitStream *bs)
594 {
595 u32 count, i;
596 GF_Err e;
597 GF_ItemProtectionBox *ptr = (GF_ItemProtectionBox *)s;
598 if (!s) return GF_BAD_PARAM;
599 e = gf_isom_full_box_write(s, bs);
600 if (e) return e;
601 count = gf_list_count(ptr->protection_information);
602 gf_bs_write_u16(bs, count);
603 if (count) {
604 for (i = 0; i < count; i++) {
605 GF_Box *a = (GF_Box *)gf_list_get(ptr->protection_information, i);
606 e = gf_isom_box_write(a, bs);
607 if (e) return e;
608 }
609 }
610 return GF_OK;
611 }
612
ipro_Size(GF_Box * s)613 GF_Err ipro_Size(GF_Box *s)
614 {
615 u32 i, count;
616 GF_Err e;
617 GF_ItemProtectionBox *ptr = (GF_ItemProtectionBox *)s;
618 if (!s) return GF_BAD_PARAM;
619 e = gf_isom_full_box_get_size(s);
620 if (e) return e;
621 ptr->size += 2;
622 if ((count = gf_list_count(ptr->protection_information))) {
623 for (i = 0; i < count; i++) {
624 GF_Box *a = (GF_Box *)gf_list_get(ptr->protection_information, i);
625 e = gf_isom_box_size(a);
626 if (e) return e;
627 ptr->size += a->size;
628 }
629 }
630 return GF_OK;
631 }
632 #endif /*GPAC_DISABLE_ISOM_WRITE*/
633
infe_New()634 GF_Box *infe_New()
635 {
636 ISOM_DECL_BOX_ALLOC(GF_ItemInfoEntryBox, GF_ISOM_BOX_TYPE_INFE);
637 gf_isom_full_box_init((GF_Box *)tmp);
638 return (GF_Box *)tmp;
639 }
640
infe_del(GF_Box * s)641 void infe_del(GF_Box *s)
642 {
643 GF_ItemInfoEntryBox *ptr = (GF_ItemInfoEntryBox *)s;
644 if (ptr == NULL) return;
645 if (ptr->item_name) gf_free(ptr->item_name);
646 if (ptr->full_path) gf_free(ptr->full_path);
647 if (ptr->content_type) gf_free(ptr->content_type);
648 if (ptr->content_encoding) gf_free(ptr->content_encoding);
649 gf_free(ptr);
650 }
651
infe_Read(GF_Box * s,GF_BitStream * bs)652 GF_Err infe_Read(GF_Box *s, GF_BitStream *bs)
653 {
654 GF_Err e;
655 char *buf;
656 u32 buf_len, i, string_len, string_start;
657 GF_ItemInfoEntryBox *ptr = (GF_ItemInfoEntryBox *)s;
658 if (ptr == NULL) return GF_BAD_PARAM;
659 e = gf_isom_full_box_read(s, bs);
660 if (e) return e;
661
662 ptr->item_ID = gf_bs_read_u16(bs);
663 ptr->item_protection_index = gf_bs_read_u16(bs);
664 ptr->size -= 4;
665 if (ptr->version == 2) {
666 ptr->item_type = gf_bs_read_u32(bs);
667 ptr->size -= 4;
668 }
669 buf_len = (u32)(ptr->size);
670 buf = (char*)gf_malloc(buf_len);
671 if (buf_len != gf_bs_read_data(bs, buf, buf_len)) {
672 gf_free(buf);
673 return GF_ISOM_INVALID_FILE;
674 }
675 string_len = 1;
676 string_start = 0;
677 for (i = 0; i < buf_len; i++) {
678 if (buf[i] == 0) {
679 if (!ptr->item_name) {
680 ptr->item_name = (char*)gf_malloc(sizeof(char)*string_len);
681 memcpy(ptr->item_name, buf + string_start, string_len);
682 }
683 else if (!ptr->content_type) {
684 ptr->content_type = (char*)gf_malloc(sizeof(char)*string_len);
685 memcpy(ptr->content_type, buf + string_start, string_len);
686 }
687 else {
688 ptr->content_encoding = (char*)gf_malloc(sizeof(char)*string_len);
689 memcpy(ptr->content_encoding, buf + string_start, string_len);
690 }
691 string_start += string_len;
692 string_len = 0;
693 }
694 string_len++;
695 }
696 gf_free(buf);
697 if (!ptr->item_name || (!ptr->content_type && ptr->version < 2)) return GF_ISOM_INVALID_FILE;
698 return GF_OK;
699 }
700
701 #ifndef GPAC_DISABLE_ISOM_WRITE
infe_Write(GF_Box * s,GF_BitStream * bs)702 GF_Err infe_Write(GF_Box *s, GF_BitStream *bs)
703 {
704 GF_Err e;
705 u32 len;
706 GF_ItemInfoEntryBox *ptr = (GF_ItemInfoEntryBox *)s;
707 if (!s) return GF_BAD_PARAM;
708 e = gf_isom_full_box_write(s, bs);
709 if (e) return e;
710 if (ptr->version == 3) {
711 gf_bs_write_u32(bs, ptr->item_ID);
712 }
713 else {
714 gf_bs_write_u16(bs, ptr->item_ID);
715 }
716 gf_bs_write_u16(bs, ptr->item_protection_index);
717 if (ptr->version >= 2) {
718 gf_bs_write_u32(bs, ptr->item_type);
719 }
720 if (ptr->item_name) {
721 len = (u32)strlen(ptr->item_name) + 1;
722 gf_bs_write_data(bs, ptr->item_name, len);
723 }
724 else {
725 gf_bs_write_byte(bs, 0, 1);
726 }
727 if (ptr->item_type == GF_4CC('m', 'i', 'm', 'e') || ptr->item_type == GF_4CC('u', 'r', 'i', ' ')) {
728 if (ptr->content_type) {
729 len = (u32)strlen(ptr->content_type) + 1;
730 gf_bs_write_data(bs, ptr->content_type, len);
731 }
732 else {
733 gf_bs_write_byte(bs, 0, 1);
734 }
735 }
736 if (ptr->item_type == GF_4CC('m', 'i', 'm', 'e')) {
737 if (ptr->content_encoding) {
738 len = (u32)strlen(ptr->content_encoding) + 1;
739 gf_bs_write_data(bs, ptr->content_encoding, len);
740 }
741 else {
742 gf_bs_write_byte(bs, 0, 1);
743 }
744 }
745 return GF_OK;
746 }
747
infe_Size(GF_Box * s)748 GF_Err infe_Size(GF_Box *s)
749 {
750 GF_Err e;
751 GF_ItemInfoEntryBox *ptr = (GF_ItemInfoEntryBox *)s;
752 if (!s) return GF_BAD_PARAM;
753 e = gf_isom_full_box_get_size(s);
754 if (e) return e;
755 if (ptr->item_type) {
756 ptr->version = 2;
757 if (ptr->item_ID > 0xFFFF) {
758 ptr->version = 3;
759 }
760 }
761 else {
762 ptr->version = 0;
763 }
764 ptr->size += 4;
765 if (ptr->version == 3) {
766 ptr->size += 2; // item_ID on 32 bits (+2 bytes)
767 }
768 if (ptr->version >= 2) {
769 ptr->size += 4; // item_type size
770 }
771 if (ptr->item_name) ptr->size += strlen(ptr->item_name) + 1;
772 else ptr->size += 1;
773 if (ptr->item_type == GF_4CC('m', 'i', 'm', 'e') || ptr->item_type == GF_4CC('u', 'r', 'i', ' ')) {
774 if (ptr->content_type) ptr->size += strlen(ptr->content_type) + 1;
775 else ptr->size += 1;
776 }
777 if (ptr->item_type == GF_4CC('m', 'i', 'm', 'e')) {
778 if (ptr->content_encoding) ptr->size += strlen(ptr->content_encoding) + 1;
779 else ptr->size += 1;
780 }
781 return GF_OK;
782 }
783 #endif /*GPAC_DISABLE_ISOM_WRITE*/
784
iinf_New()785 GF_Box *iinf_New()
786 {
787 ISOM_DECL_BOX_ALLOC(GF_ItemInfoBox, GF_ISOM_BOX_TYPE_IINF);
788 gf_isom_full_box_init((GF_Box *)tmp);
789 tmp->item_infos = gf_list_new();
790 return (GF_Box *)tmp;
791 }
792
iinf_del(GF_Box * s)793 void iinf_del(GF_Box *s)
794 {
795 u32 count, i;
796 GF_ItemInfoBox *ptr = (GF_ItemInfoBox *)s;
797 if (ptr == NULL) return;
798 count = gf_list_count(ptr->item_infos);
799 for (i = 0; i < count; i++) {
800 GF_Box *a = (GF_Box *)gf_list_get(ptr->item_infos, i);
801 gf_isom_box_del(a);
802 }
803 gf_list_del(ptr->item_infos);
804 gf_free(ptr);
805 }
806
iinf_Read(GF_Box * s,GF_BitStream * bs)807 GF_Err iinf_Read(GF_Box *s, GF_BitStream *bs)
808 {
809 GF_Err e;
810 GF_Box *a;
811 u32 count;
812 GF_ItemInfoBox *ptr = (GF_ItemInfoBox *)s;
813
814 e = gf_isom_full_box_read(s, bs);
815 if (e) return e;
816 if (ptr->version == 0) {
817 count = gf_bs_read_u16(bs);
818 }
819 else {
820 count = gf_bs_read_u32(bs);
821 }
822
823 while (count) {
824 e = gf_isom_parse_box(&a, bs);
825 if (e) return e;
826 if (ptr->size<a->size) return GF_ISOM_INVALID_FILE;
827
828 if (a->type == GF_ISOM_BOX_TYPE_INFE)
829 gf_list_add(ptr->item_infos, a);
830 else
831 gf_isom_box_del(a);
832 count--;
833 }
834 return GF_OK;
835 }
836
837 #ifndef GPAC_DISABLE_ISOM_WRITE
iinf_Write(GF_Box * s,GF_BitStream * bs)838 GF_Err iinf_Write(GF_Box *s, GF_BitStream *bs)
839 {
840 u32 count, i;
841 GF_Err e;
842 GF_ItemInfoBox *ptr = (GF_ItemInfoBox *)s;
843 if (!s) return GF_BAD_PARAM;
844 e = gf_isom_full_box_write(s, bs);
845 if (e) return e;
846 count = gf_list_count(ptr->item_infos);
847 gf_bs_write_u16(bs, count);
848 if (count) {
849 for (i = 0; i < count; i++) {
850 GF_Box *a = (GF_Box *)gf_list_get(ptr->item_infos, i);
851 e = gf_isom_box_write(a, bs);
852 if (e) return e;
853 }
854 }
855 return GF_OK;
856 }
857
iinf_Size(GF_Box * s)858 GF_Err iinf_Size(GF_Box *s)
859 {
860 u32 i, count;
861 GF_Err e;
862 GF_ItemInfoBox *ptr = (GF_ItemInfoBox *)s;
863 if (!s) return GF_BAD_PARAM;
864 e = gf_isom_full_box_get_size(s);
865 if (e) return e;
866 ptr->size += 2;
867 if ((count = gf_list_count(ptr->item_infos))) {
868 for (i = 0; i < count; i++) {
869 GF_Box *a = (GF_Box *)gf_list_get(ptr->item_infos, i);
870 e = gf_isom_box_size(a);
871 if (e) return e;
872 ptr->size += a->size;
873 }
874 }
875 return GF_OK;
876 }
877 #endif /*GPAC_DISABLE_ISOM_WRITE*/
878
iref_AddBox(GF_Box * s,GF_Box * a)879 GF_Err iref_AddBox(GF_Box *s, GF_Box *a)
880 {
881 GF_ItemReferenceBox *ptr = (GF_ItemReferenceBox *)s;
882 return gf_list_add(ptr->references, a);
883 }
884
iref_del(GF_Box * s)885 void iref_del(GF_Box *s)
886 {
887 u32 count, i;
888 GF_ItemReferenceBox *ptr = (GF_ItemReferenceBox *)s;
889 if (ptr == NULL) return;
890 count = gf_list_count(ptr->references);
891 for (i = 0; i < count; i++) {
892 GF_Box *a = (GF_Box *)gf_list_get(ptr->references, i);
893 gf_isom_box_del(a);
894 }
895 gf_list_del(ptr->references);
896 gf_free(ptr);
897 }
898
899
iref_Read(GF_Box * s,GF_BitStream * bs)900 GF_Err iref_Read(GF_Box *s, GF_BitStream *bs)
901 {
902 GF_Err e;
903 e = gf_isom_full_box_read(s, bs);
904 if (e) return e;
905 return gf_isom_read_box_list_ex(s, bs, iref_AddBox, s->type);
906 }
907
iref_New()908 GF_Box *iref_New()
909 {
910 ISOM_DECL_BOX_ALLOC(GF_ItemReferenceBox, GF_ISOM_BOX_TYPE_IREF);
911 tmp->references = gf_list_new();
912 return (GF_Box *)tmp;
913 }
914
915 #ifndef GPAC_DISABLE_ISOM_WRITE
916
iref_Write(GF_Box * s,GF_BitStream * bs)917 GF_Err iref_Write(GF_Box *s, GF_BitStream *bs)
918 {
919 GF_Err e;
920 u32 count, i;
921 GF_ItemReferenceBox *ptr = (GF_ItemReferenceBox *)s;
922 if (!s) return GF_BAD_PARAM;
923 e = gf_isom_full_box_write(s, bs);
924 if (e) return e;
925 count = gf_list_count(ptr->references);
926 for (i = 0; i < count; i++) {
927 GF_Box *a = (GF_Box *)gf_list_get(ptr->references, i);
928 e = gf_isom_box_write(a, bs);
929 if (e) return e;
930 }
931 return e;
932 }
933
iref_Size(GF_Box * s)934 GF_Err iref_Size(GF_Box *s)
935 {
936 GF_Err e;
937 u32 count, i;
938 GF_ItemReferenceBox *ptr = (GF_ItemReferenceBox *)s;
939 if (!s) return GF_BAD_PARAM;
940 e = gf_isom_full_box_get_size(s);
941 if (e) return e;
942 count = gf_list_count(ptr->references);
943 for (i = 0; i < count; i++) {
944 GF_Box *a = (GF_Box *)gf_list_get(ptr->references, i);
945 e = gf_isom_box_size(a);
946 if (e) return e;
947 s->size += a->size;
948 }
949 return e;
950 }
951
952 #endif /*GPAC_DISABLE_ISOM_WRITE*/
953
ireftype_del(GF_Box * s)954 void ireftype_del(GF_Box *s)
955 {
956 GF_ItemReferenceTypeBox *ptr = (GF_ItemReferenceTypeBox *)s;
957 if (!ptr) return;
958 if (ptr->to_item_IDs) gf_free(ptr->to_item_IDs);
959 gf_free(ptr);
960 }
961
ireftype_Read(GF_Box * s,GF_BitStream * bs)962 GF_Err ireftype_Read(GF_Box *s, GF_BitStream *bs)
963 {
964 u32 bytesToRead;
965 u32 i;
966 GF_ItemReferenceTypeBox *ptr = (GF_ItemReferenceTypeBox *)s;
967
968 bytesToRead = (u32)(ptr->size);
969 if (!bytesToRead) return GF_OK;
970
971 ptr->from_item_id = gf_bs_read_u16(bs);
972 ptr->reference_count = gf_bs_read_u16(bs);
973 ptr->to_item_IDs = (u32 *)gf_malloc(ptr->reference_count * sizeof(u32));
974 if (!ptr->to_item_IDs) return GF_OUT_OF_MEM;
975
976 for (i = 0; i < ptr->reference_count; i++) {
977 ptr->to_item_IDs[i] = gf_bs_read_u16(bs);
978 }
979 return GF_OK;
980 }
981
ireftype_New()982 GF_Box *ireftype_New()
983 {
984 ISOM_DECL_BOX_ALLOC(GF_ItemReferenceTypeBox, GF_ISOM_BOX_TYPE_REFI);
985 return (GF_Box *)tmp;
986 }
987
988 #ifndef GPAC_DISABLE_ISOM_WRITE
989
ireftype_Write(GF_Box * s,GF_BitStream * bs)990 GF_Err ireftype_Write(GF_Box *s, GF_BitStream *bs)
991 {
992 GF_Err e;
993 u32 i;
994 GF_ItemReferenceTypeBox *ptr = (GF_ItemReferenceTypeBox *)s;
995 ptr->type = ptr->reference_type;
996 e = gf_isom_box_write_header(s, bs);
997 ptr->type = GF_ISOM_BOX_TYPE_REFI;
998 if (e) return e;
999 gf_bs_write_u16(bs, ptr->from_item_id);
1000 gf_bs_write_u16(bs, ptr->reference_count);
1001 for (i = 0; i < ptr->reference_count; i++) {
1002 gf_bs_write_u16(bs, ptr->to_item_IDs[i]);
1003 }
1004 return GF_OK;
1005 }
1006
1007
ireftype_Size(GF_Box * s)1008 GF_Err ireftype_Size(GF_Box *s)
1009 {
1010 GF_Err e;
1011 GF_ItemReferenceTypeBox *ptr = (GF_ItemReferenceTypeBox *)s;
1012 e = gf_isom_box_get_size(s);
1013 if (e) return e;
1014 ptr->size += 4 + (ptr->reference_count * sizeof(u16));
1015 return GF_OK;
1016 }
1017
1018 #endif /*GPAC_DISABLE_ISOM_WRITE*/
1019 #endif /*GPAC_DISABLE_ISOM*/
1020
1021