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 
30 /* ProtectionInfo Box */
sinf_New()31 GF_Box *sinf_New()
32 {
33 	ISOM_DECL_BOX_ALLOC(GF_ProtectionInfoBox, GF_ISOM_BOX_TYPE_SINF);
34 	return (GF_Box *)tmp;
35 }
36 
sinf_del(GF_Box * s)37 void sinf_del(GF_Box *s)
38 {
39 	GF_ProtectionInfoBox *ptr = (GF_ProtectionInfoBox *)s;
40 	if (ptr == NULL) return;
41 	if (ptr->original_format) gf_isom_box_del((GF_Box *)ptr->original_format);
42 	if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info);
43 	if (ptr->scheme_type) gf_isom_box_del((GF_Box *)ptr->scheme_type);
44 	gf_free(ptr);
45 }
46 
sinf_AddBox(GF_Box * s,GF_Box * a)47 GF_Err sinf_AddBox(GF_Box *s, GF_Box *a)
48 {
49 	GF_ProtectionInfoBox *ptr = (GF_ProtectionInfoBox *)s;
50 	switch (a->type) {
51 	case GF_ISOM_BOX_TYPE_FRMA:
52 		if (ptr->original_format) return GF_ISOM_INVALID_FILE;
53 		ptr->original_format = (GF_OriginalFormatBox*)a;
54 		break;
55 	case GF_ISOM_BOX_TYPE_SCHM:
56 		if (ptr->scheme_type) return GF_ISOM_INVALID_FILE;
57 		ptr->scheme_type = (GF_SchemeTypeBox*)a;
58 		break;
59 	case GF_ISOM_BOX_TYPE_SCHI:
60 		if (ptr->info) return GF_ISOM_INVALID_FILE;
61 		ptr->info = (GF_SchemeInformationBox*)a;
62 		break;
63 	default:
64 		return gf_isom_box_add_default(s, a);
65 	}
66 	return GF_OK;
67 }
68 
sinf_Read(GF_Box * s,GF_BitStream * bs)69 GF_Err sinf_Read(GF_Box *s, GF_BitStream *bs)
70 {
71 	return gf_isom_read_box_list(s, bs, sinf_AddBox);
72 }
73 
74 #ifndef GPAC_DISABLE_ISOM_WRITE
sinf_Write(GF_Box * s,GF_BitStream * bs)75 GF_Err sinf_Write(GF_Box *s, GF_BitStream *bs)
76 {
77 	GF_Err e;
78 	GF_ProtectionInfoBox *ptr = (GF_ProtectionInfoBox *)s;
79 	if (!s) return GF_BAD_PARAM;
80 	e = gf_isom_box_write_header(s, bs);
81 	if (e) return e;
82 	//frma
83 	e = gf_isom_box_write((GF_Box *)ptr->original_format, bs);
84 	if (e) return e;
85 	// schm
86 	e = gf_isom_box_write((GF_Box *)ptr->scheme_type, bs);
87 	if (e) return e;
88 	// schi
89 	e = gf_isom_box_write((GF_Box *)ptr->info, bs);
90 	if (e) return e;
91 	return GF_OK;
92 }
93 
sinf_Size(GF_Box * s)94 GF_Err sinf_Size(GF_Box *s)
95 {
96 	GF_Err e;
97 	GF_ProtectionInfoBox *ptr = (GF_ProtectionInfoBox *)s;
98 	if (!s) return GF_BAD_PARAM;
99 	e = gf_isom_box_get_size(s);
100 	if (e) return e;
101 	e = gf_isom_box_size((GF_Box *)ptr->original_format);
102 	if (e) return e;
103 	ptr->size += ptr->original_format->size;
104 	e = gf_isom_box_size((GF_Box *)ptr->scheme_type);
105 	if (e) return e;
106 	ptr->size += ptr->scheme_type->size;
107 	e = gf_isom_box_size((GF_Box *)ptr->info);
108 	if (e) return e;
109 	ptr->size += ptr->info->size;
110 	return GF_OK;
111 }
112 #endif /*GPAC_DISABLE_ISOM_WRITE*/
113 
114 /* OriginalFormat Box */
frma_New()115 GF_Box *frma_New()
116 {
117 	ISOM_DECL_BOX_ALLOC(GF_OriginalFormatBox, GF_ISOM_BOX_TYPE_FRMA);
118 	return (GF_Box *)tmp;
119 }
120 
frma_del(GF_Box * s)121 void frma_del(GF_Box *s)
122 {
123 	GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
124 	if (ptr == NULL) return;
125 	gf_free(ptr);
126 }
127 
frma_Read(GF_Box * s,GF_BitStream * bs)128 GF_Err frma_Read(GF_Box *s, GF_BitStream *bs)
129 {
130 	GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
131 	ptr->data_format = gf_bs_read_u32(bs);
132 	return GF_OK;
133 }
134 
135 #ifndef GPAC_DISABLE_ISOM_WRITE
frma_Write(GF_Box * s,GF_BitStream * bs)136 GF_Err frma_Write(GF_Box *s, GF_BitStream *bs)
137 {
138 	GF_Err e;
139 	GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
140 	if (!s) return GF_BAD_PARAM;
141 	e = gf_isom_box_write_header(s, bs);
142 	if (e) return e;
143 	gf_bs_write_u32(bs, ptr->data_format);
144 	return GF_OK;
145 }
146 
frma_Size(GF_Box * s)147 GF_Err frma_Size(GF_Box *s)
148 {
149 	GF_Err e;
150 	GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
151 	if (!s) return GF_BAD_PARAM;
152 	e = gf_isom_box_get_size(s);
153 	if (e) return e;
154 	ptr->size += 4;
155 	return GF_OK;
156 }
157 #endif /*GPAC_DISABLE_ISOM_WRITE*/
158 
159 /* SchemeType Box */
schm_New()160 GF_Box *schm_New()
161 {
162 	ISOM_DECL_BOX_ALLOC(GF_SchemeTypeBox, GF_ISOM_BOX_TYPE_SCHM);
163 	gf_isom_full_box_init((GF_Box *)tmp);
164 	return (GF_Box *)tmp;
165 }
166 
schm_del(GF_Box * s)167 void schm_del(GF_Box *s)
168 {
169 	GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
170 	if (ptr == NULL) return;
171 	if (ptr->URI) gf_free(ptr->URI);
172 	gf_free(ptr);
173 }
174 
schm_Read(GF_Box * s,GF_BitStream * bs)175 GF_Err schm_Read(GF_Box *s, GF_BitStream *bs)
176 {
177 	GF_Err e;
178 	GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
179 	e = gf_isom_full_box_read(s, bs);
180 	if (e) return e;
181 	ptr->scheme_type = gf_bs_read_u32(bs);
182 	ptr->scheme_version = gf_bs_read_u32(bs);
183 	ptr->size -= 8;
184 	if (ptr->size && (ptr->flags & 0x000001)) {
185 		u32 len = (u32)(ptr->size);
186 		ptr->URI = (char*)gf_malloc(sizeof(char)*len);
187 		if (!ptr->URI) return GF_OUT_OF_MEM;
188 		gf_bs_read_data(bs, ptr->URI, len);
189 	}
190 	return GF_OK;
191 }
192 
193 #ifndef GPAC_DISABLE_ISOM_WRITE
schm_Write(GF_Box * s,GF_BitStream * bs)194 GF_Err schm_Write(GF_Box *s, GF_BitStream *bs)
195 {
196 	GF_Err e;
197 	GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
198 	if (!s) return GF_BAD_PARAM;
199 	e = gf_isom_full_box_write(s, bs);
200 	if (e) return e;
201 	gf_bs_write_u32(bs, ptr->scheme_type);
202 	gf_bs_write_u32(bs, ptr->scheme_version);
203 	if (ptr->flags & 0x000001) gf_bs_write_data(bs, ptr->URI, (u32)strlen(ptr->URI) + 1);
204 	return GF_OK;
205 }
206 
schm_Size(GF_Box * s)207 GF_Err schm_Size(GF_Box *s)
208 {
209 	GF_Err e;
210 	GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
211 	if (!s) return GF_BAD_PARAM;
212 	e = gf_isom_full_box_get_size(s);
213 	if (e) return e;
214 	ptr->size += 8;
215 	if (ptr->flags & 0x000001) ptr->size += strlen(ptr->URI) + 1;
216 	return GF_OK;
217 }
218 #endif /*GPAC_DISABLE_ISOM_WRITE*/
219 
220 /* SchemeInformation Box */
schi_New()221 GF_Box *schi_New()
222 {
223 	ISOM_DECL_BOX_ALLOC(GF_SchemeInformationBox, GF_ISOM_BOX_TYPE_SCHI);
224 	return (GF_Box *)tmp;
225 }
226 
schi_del(GF_Box * s)227 void schi_del(GF_Box *s)
228 {
229 	GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
230 	if (ptr == NULL) return;
231 	if (ptr->ikms) gf_isom_box_del((GF_Box *)ptr->ikms);
232 	if (ptr->isfm) gf_isom_box_del((GF_Box *)ptr->isfm);
233 	if (ptr->okms) gf_isom_box_del((GF_Box *)ptr->okms);
234 	if (ptr->tenc) gf_isom_box_del((GF_Box *)ptr->tenc);
235 	if (ptr->piff_tenc) gf_isom_box_del((GF_Box *)ptr->piff_tenc);
236 	if (ptr->adkm) gf_isom_box_del((GF_Box *)ptr->adkm);
237 	gf_free(ptr);
238 }
239 
schi_AddBox(GF_Box * s,GF_Box * a)240 GF_Err schi_AddBox(GF_Box *s, GF_Box *a)
241 {
242 	GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
243 	switch (a->type) {
244 	case GF_ISOM_BOX_TYPE_IKMS:
245 		if (ptr->ikms) return GF_ISOM_INVALID_FILE;
246 		ptr->ikms = (GF_ISMAKMSBox*)a;
247 		return GF_OK;
248 	case GF_ISOM_BOX_TYPE_ISFM:
249 		if (ptr->isfm) return GF_ISOM_INVALID_FILE;
250 		ptr->isfm = (GF_ISMASampleFormatBox*)a;
251 		return GF_OK;
252 	case GF_ISOM_BOX_TYPE_ODKM:
253 		if (ptr->okms) return GF_ISOM_INVALID_FILE;
254 		ptr->okms = (GF_OMADRMKMSBox*)a;
255 		return GF_OK;
256 	case GF_ISOM_BOX_TYPE_TENC:
257 		if (ptr->tenc) return GF_ISOM_INVALID_FILE;
258 		ptr->tenc = (GF_TrackEncryptionBox *)a;
259 		return GF_OK;
260 	case GF_ISOM_BOX_TYPE_ADKM:
261 		if (ptr->adkm) return GF_ISOM_INVALID_FILE;
262 		ptr->adkm = (GF_AdobeDRMKeyManagementSystemBox *)a;
263 		return GF_OK;
264 	case GF_ISOM_BOX_TYPE_UUID:
265 		if (((GF_UUIDBox*)a)->internal_4cc == GF_ISOM_BOX_UUID_TENC) {
266 			if (ptr->piff_tenc) return GF_ISOM_INVALID_FILE;
267 			ptr->piff_tenc = (GF_PIFFTrackEncryptionBox *)a;
268 			return GF_OK;
269 		}
270 		else {
271 			return gf_isom_box_add_default(s, a);
272 		}
273 	default:
274 		return gf_isom_box_add_default(s, a);
275 	}
276 }
277 
schi_Read(GF_Box * s,GF_BitStream * bs)278 GF_Err schi_Read(GF_Box *s, GF_BitStream *bs)
279 {
280 	return gf_isom_read_box_list(s, bs, schi_AddBox);
281 }
282 
283 #ifndef GPAC_DISABLE_ISOM_WRITE
schi_Write(GF_Box * s,GF_BitStream * bs)284 GF_Err schi_Write(GF_Box *s, GF_BitStream *bs)
285 {
286 	GF_Err e;
287 	GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
288 	if (!s) return GF_BAD_PARAM;
289 	e = gf_isom_box_write_header(s, bs);
290 	if (e) return e;
291 
292 	if (ptr->ikms) {
293 		e = gf_isom_box_write((GF_Box *)ptr->ikms, bs);
294 		if (e) return e;
295 	}
296 	if (ptr->isfm) {
297 		e = gf_isom_box_write((GF_Box *)ptr->isfm, bs);
298 		if (e) return e;
299 	}
300 	if (ptr->okms) {
301 		e = gf_isom_box_write((GF_Box *)ptr->okms, bs);
302 		if (e) return e;
303 	}
304 	if (ptr->tenc) {
305 		e = gf_isom_box_write((GF_Box *)ptr->tenc, bs);
306 		if (e) return e;
307 	}
308 	if (ptr->adkm) {
309 		e = gf_isom_box_write((GF_Box *)ptr->adkm, bs);
310 		if (e) return e;
311 	}
312 	if (ptr->piff_tenc) {
313 		e = gf_isom_box_write((GF_Box *)ptr->piff_tenc, bs);
314 		if (e) return e;
315 	}
316 	return GF_OK;
317 }
318 
schi_Size(GF_Box * s)319 GF_Err schi_Size(GF_Box *s)
320 {
321 	GF_Err e;
322 	GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
323 	if (!s) return GF_BAD_PARAM;
324 	e = gf_isom_box_get_size(s);
325 	if (e) return e;
326 
327 	if (ptr->ikms) {
328 		e = gf_isom_box_size((GF_Box *)ptr->ikms);
329 		if (e) return e;
330 		ptr->size += ptr->ikms->size;
331 	}
332 	if (ptr->isfm) {
333 		e = gf_isom_box_size((GF_Box *)ptr->isfm);
334 		if (e) return e;
335 		ptr->size += ptr->isfm->size;
336 	}
337 	if (ptr->okms) {
338 		e = gf_isom_box_size((GF_Box *)ptr->okms);
339 		if (e) return e;
340 		ptr->size += ptr->okms->size;
341 	}
342 	if (ptr->tenc) {
343 		e = gf_isom_box_size((GF_Box *)ptr->tenc);
344 		if (e) return e;
345 		ptr->size += ptr->tenc->size;
346 	}
347 	if (ptr->adkm) {
348 		e = gf_isom_box_size((GF_Box *)ptr->adkm);
349 		if (e) return e;
350 		ptr->size += ptr->adkm->size;
351 	}
352 	if (ptr->piff_tenc) {
353 		e = gf_isom_box_size((GF_Box *)ptr->piff_tenc);
354 		if (e) return e;
355 		ptr->size += ptr->piff_tenc->size;
356 	}
357 	return GF_OK;
358 }
359 
360 #endif /*GPAC_DISABLE_ISOM_WRITE*/
361 
362 /* ISMAKMS Box */
iKMS_New()363 GF_Box *iKMS_New()
364 {
365 	ISOM_DECL_BOX_ALLOC(GF_ISMAKMSBox, GF_ISOM_BOX_TYPE_IKMS);
366 	gf_isom_full_box_init((GF_Box *)tmp);
367 	return (GF_Box *)tmp;
368 }
369 
iKMS_del(GF_Box * s)370 void iKMS_del(GF_Box *s)
371 {
372 	GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
373 	if (ptr == NULL) return;
374 	if (ptr->URI) gf_free(ptr->URI);
375 	gf_free(ptr);
376 }
377 
iKMS_Read(GF_Box * s,GF_BitStream * bs)378 GF_Err iKMS_Read(GF_Box *s, GF_BitStream *bs)
379 {
380 	GF_Err e;
381 	u32 len;
382 	GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
383 
384 	e = gf_isom_full_box_read(s, bs);
385 	if (e) return e;
386 	len = (u32)(ptr->size);
387 	ptr->URI = (char*)gf_malloc(sizeof(char)*len);
388 	if (!ptr->URI) return GF_OUT_OF_MEM;
389 	gf_bs_read_data(bs, ptr->URI, len);
390 	return GF_OK;
391 }
392 
393 #ifndef GPAC_DISABLE_ISOM_WRITE
iKMS_Write(GF_Box * s,GF_BitStream * bs)394 GF_Err iKMS_Write(GF_Box *s, GF_BitStream *bs)
395 {
396 	GF_Err e;
397 	GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
398 	if (!s) return GF_BAD_PARAM;
399 	e = gf_isom_full_box_write(s, bs);
400 	if (e) return e;
401 	gf_bs_write_data(bs, ptr->URI, (u32)strlen(ptr->URI) + 1);
402 	return GF_OK;
403 }
404 
iKMS_Size(GF_Box * s)405 GF_Err iKMS_Size(GF_Box *s)
406 {
407 	GF_Err e;
408 	GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
409 	if (!s) return GF_BAD_PARAM;
410 	e = gf_isom_full_box_get_size(s);
411 	if (e) return e;
412 	ptr->size += strlen(ptr->URI) + 1;
413 	return GF_OK;
414 }
415 #endif /*GPAC_DISABLE_ISOM_WRITE*/
416 
417 /* ISMASampleFormat Box */
iSFM_New()418 GF_Box *iSFM_New()
419 {
420 	ISOM_DECL_BOX_ALLOC(GF_ISMASampleFormatBox, GF_ISOM_BOX_TYPE_ISFM);
421 	gf_isom_full_box_init((GF_Box *)tmp);
422 	return (GF_Box *)tmp;
423 }
424 
iSFM_del(GF_Box * s)425 void iSFM_del(GF_Box *s)
426 {
427 	GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
428 	if (ptr == NULL) return;
429 	gf_free(ptr);
430 }
431 
432 
iSFM_Read(GF_Box * s,GF_BitStream * bs)433 GF_Err iSFM_Read(GF_Box *s, GF_BitStream *bs)
434 {
435 	GF_Err e;
436 	GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
437 	if (ptr == NULL) return GF_BAD_PARAM;
438 	e = gf_isom_full_box_read(s, bs);
439 	if (e) return e;
440 	ptr->selective_encryption = gf_bs_read_int(bs, 1);
441 	gf_bs_read_int(bs, 7);
442 	ptr->key_indicator_length = gf_bs_read_u8(bs);
443 	ptr->IV_length = gf_bs_read_u8(bs);
444 	return GF_OK;
445 }
446 
447 #ifndef GPAC_DISABLE_ISOM_WRITE
iSFM_Write(GF_Box * s,GF_BitStream * bs)448 GF_Err iSFM_Write(GF_Box *s, GF_BitStream *bs)
449 {
450 	GF_Err e;
451 	GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
452 	if (!s) return GF_BAD_PARAM;
453 	e = gf_isom_full_box_write(s, bs);
454 	if (e) return e;
455 	gf_bs_write_int(bs, ptr->selective_encryption, 1);
456 	gf_bs_write_int(bs, 0, 7);
457 	gf_bs_write_u8(bs, ptr->key_indicator_length);
458 	gf_bs_write_u8(bs, ptr->IV_length);
459 	return GF_OK;
460 }
461 
iSFM_Size(GF_Box * s)462 GF_Err iSFM_Size(GF_Box *s)
463 {
464 	GF_Err e;
465 	GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
466 	if (!s) return GF_BAD_PARAM;
467 	e = gf_isom_full_box_get_size(s);
468 	if (e) return e;
469 	ptr->size += 3;
470 	return GF_OK;
471 }
472 #endif /*GPAC_DISABLE_ISOM_WRITE*/
473 
474 
475 
476 /* OMADRMCommonHeader Box */
ohdr_New()477 GF_Box *ohdr_New()
478 {
479 	ISOM_DECL_BOX_ALLOC(GF_OMADRMCommonHeaderBox, GF_ISOM_BOX_TYPE_OHDR);
480 	gf_isom_full_box_init((GF_Box *)tmp);
481 	tmp->other_boxes = gf_list_new();
482 	return (GF_Box *)tmp;
483 }
484 
ohdr_del(GF_Box * s)485 void ohdr_del(GF_Box *s)
486 {
487 	GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;
488 	if (ptr == NULL) return;
489 	if (ptr->ContentID) gf_free(ptr->ContentID);
490 	if (ptr->RightsIssuerURL) gf_free(ptr->RightsIssuerURL);
491 	if (ptr->TextualHeaders) gf_free(ptr->TextualHeaders);
492 	gf_free(ptr);
493 }
494 
ohdr_AddBox(GF_Box * s,GF_Box * a)495 GF_Err ohdr_AddBox(GF_Box *s, GF_Box *a)
496 {
497 	return gf_isom_box_add_default(s, a);
498 }
499 
ohdr_Read(GF_Box * s,GF_BitStream * bs)500 GF_Err ohdr_Read(GF_Box *s, GF_BitStream *bs)
501 {
502 	u16 cid_len, ri_len;
503 	GF_Err e;
504 	GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;
505 	if (ptr == NULL) return GF_BAD_PARAM;
506 	e = gf_isom_full_box_read(s, bs);
507 	if (e) return e;
508 	ptr->EncryptionMethod = gf_bs_read_u8(bs);
509 	ptr->PaddingScheme = gf_bs_read_u8(bs);
510 	ptr->PlaintextLength = gf_bs_read_u64(bs);
511 	cid_len = gf_bs_read_u16(bs);
512 	ri_len = gf_bs_read_u16(bs);
513 	ptr->TextualHeadersLen = gf_bs_read_u16(bs);
514 	ptr->size -= 1 + 1 + 8 + 2 + 2 + 2;
515 	if (ptr->size<cid_len + ri_len + ptr->TextualHeadersLen) return GF_ISOM_INVALID_FILE;
516 
517 	if (cid_len) {
518 		ptr->ContentID = (char *)gf_malloc(sizeof(char)*(cid_len + 1));
519 		gf_bs_read_data(bs, ptr->ContentID, cid_len);
520 		ptr->ContentID[cid_len] = 0;
521 	}
522 
523 	if (ri_len) {
524 		ptr->RightsIssuerURL = (char *)gf_malloc(sizeof(char)*(ri_len + 1));
525 		gf_bs_read_data(bs, ptr->RightsIssuerURL, ri_len);
526 		ptr->RightsIssuerURL[ri_len] = 0;
527 	}
528 
529 	if (ptr->TextualHeadersLen) {
530 		ptr->TextualHeaders = (char *)gf_malloc(sizeof(char)*(ptr->TextualHeadersLen + 1));
531 		gf_bs_read_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen);
532 		ptr->TextualHeaders[ptr->TextualHeadersLen] = 0;
533 	}
534 
535 	ptr->size -= cid_len + ri_len + ptr->TextualHeadersLen;
536 
537 	return gf_isom_read_box_list(s, bs, ohdr_AddBox);
538 }
539 
540 #ifndef GPAC_DISABLE_ISOM_WRITE
ohdr_Write(GF_Box * s,GF_BitStream * bs)541 GF_Err ohdr_Write(GF_Box *s, GF_BitStream *bs)
542 {
543 	u16 cid_len, ri_len;
544 	GF_Err e;
545 	GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s;
546 	if (!s) return GF_BAD_PARAM;
547 	e = gf_isom_full_box_write(s, bs);
548 	if (e) return e;
549 	gf_bs_write_u8(bs, ptr->EncryptionMethod);
550 	gf_bs_write_u8(bs, ptr->PaddingScheme);
551 	gf_bs_write_u64(bs, ptr->PlaintextLength);
552 
553 	cid_len = ptr->ContentID ? (u16)strlen(ptr->ContentID) : 0;
554 	gf_bs_write_u16(bs, cid_len);
555 	ri_len = ptr->RightsIssuerURL ? (u16)strlen(ptr->RightsIssuerURL) : 0;
556 	gf_bs_write_u16(bs, ri_len);
557 	gf_bs_write_u16(bs, ptr->TextualHeadersLen);
558 
559 	if (cid_len) gf_bs_write_data(bs, ptr->ContentID, (u32)strlen(ptr->ContentID));
560 	if (ri_len) gf_bs_write_data(bs, ptr->RightsIssuerURL, (u32)strlen(ptr->RightsIssuerURL));
561 	if (ptr->TextualHeadersLen) gf_bs_write_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen);
562 	ptr->size -= cid_len + ri_len + ptr->TextualHeadersLen;
563 	return GF_OK;
564 }
565 
ohdr_Size(GF_Box * s)566 GF_Err ohdr_Size(GF_Box *s)
567 {
568 	GF_Err e;
569 	GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s;
570 	if (!s) return GF_BAD_PARAM;
571 	e = gf_isom_full_box_get_size(s);
572 	if (e) return e;
573 	ptr->size += 1 + 1 + 8 + 2 + 2 + 2;
574 	if (ptr->ContentID) ptr->size += strlen(ptr->ContentID);
575 	if (ptr->RightsIssuerURL) ptr->size += strlen(ptr->RightsIssuerURL);
576 	if (ptr->TextualHeadersLen) ptr->size += ptr->TextualHeadersLen;
577 	return GF_OK;
578 }
579 #endif /*GPAC_DISABLE_ISOM_WRITE*/
580 
581 
582 /* OMADRMGroupID Box */
grpi_New()583 GF_Box *grpi_New()
584 {
585 	ISOM_DECL_BOX_ALLOC(GF_OMADRMGroupIDBox, GF_ISOM_BOX_TYPE_GRPI);
586 	gf_isom_full_box_init((GF_Box *)tmp);
587 	return (GF_Box *)tmp;
588 }
589 
grpi_del(GF_Box * s)590 void grpi_del(GF_Box *s)
591 {
592 	GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
593 	if (ptr == NULL) return;
594 	if (ptr->GroupID) gf_free(ptr->GroupID);
595 	if (ptr->GroupKey) gf_free(ptr->GroupKey);
596 	gf_free(ptr);
597 }
598 
grpi_Read(GF_Box * s,GF_BitStream * bs)599 GF_Err grpi_Read(GF_Box *s, GF_BitStream *bs)
600 {
601 	u16 gid_len;
602 	GF_Err e;
603 	GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox*)s;
604 	if (ptr == NULL) return GF_BAD_PARAM;
605 	e = gf_isom_full_box_read(s, bs);
606 	if (e) return e;
607 	gid_len = gf_bs_read_u16(bs);
608 	ptr->GKEncryptionMethod = gf_bs_read_u8(bs);
609 	ptr->GKLength = gf_bs_read_u16(bs);
610 
611 	ptr->size -= 1 + 2 + 2;
612 	if (ptr->size<gid_len + ptr->GKLength) return GF_ISOM_INVALID_FILE;
613 
614 	ptr->GroupID = gf_malloc(sizeof(char)*(gid_len + 1));
615 	gf_bs_read_data(bs, ptr->GroupID, gid_len);
616 	ptr->GroupID[gid_len] = 0;
617 
618 	ptr->GroupKey = (char *)gf_malloc(sizeof(char)*ptr->GKLength);
619 	gf_bs_read_data(bs, ptr->GroupKey, ptr->GKLength);
620 	ptr->size -= gid_len + ptr->GKLength;
621 	return GF_OK;
622 }
623 
624 #ifndef GPAC_DISABLE_ISOM_WRITE
grpi_Write(GF_Box * s,GF_BitStream * bs)625 GF_Err grpi_Write(GF_Box *s, GF_BitStream *bs)
626 {
627 	GF_Err e;
628 	u16 gid_len;
629 	GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
630 	if (!s) return GF_BAD_PARAM;
631 	e = gf_isom_full_box_write(s, bs);
632 	if (e) return e;
633 	gid_len = ptr->GroupID ? (u16)strlen(ptr->GroupID) : 0;
634 	gf_bs_write_u16(bs, gid_len);
635 	gf_bs_write_u8(bs, ptr->GKEncryptionMethod);
636 	gf_bs_write_u16(bs, ptr->GKLength);
637 	gf_bs_write_data(bs, ptr->GroupID, gid_len);
638 	gf_bs_write_data(bs, ptr->GroupKey, ptr->GKLength);
639 	return GF_OK;
640 }
641 
grpi_Size(GF_Box * s)642 GF_Err grpi_Size(GF_Box *s)
643 {
644 	GF_Err e;
645 	GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
646 	if (!s) return GF_BAD_PARAM;
647 	e = gf_isom_full_box_get_size(s);
648 	if (e) return e;
649 	ptr->size += 2 + 2 + 1 + ptr->GKLength;
650 	if (ptr->GroupID) ptr->size += strlen(ptr->GroupID);
651 	return GF_OK;
652 }
653 #endif /*GPAC_DISABLE_ISOM_WRITE*/
654 
655 
656 
657 
658 /* OMADRMMutableInformation Box */
mdri_New()659 GF_Box *mdri_New()
660 {
661 	ISOM_DECL_BOX_ALLOC(GF_OMADRMMutableInformationBox, GF_ISOM_BOX_TYPE_MDRI);
662 	return (GF_Box *)tmp;
663 }
664 
mdri_del(GF_Box * s)665 void mdri_del(GF_Box *s)
666 {
667 	GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s;
668 	if (ptr == NULL) return;
669 	gf_free(ptr);
670 }
671 
mdri_Read(GF_Box * s,GF_BitStream * bs)672 GF_Err mdri_Read(GF_Box *s, GF_BitStream *bs)
673 {
674 	return gf_isom_read_box_list(s, bs, gf_isom_box_add_default);
675 }
676 
677 #ifndef GPAC_DISABLE_ISOM_WRITE
mdri_Write(GF_Box * s,GF_BitStream * bs)678 GF_Err mdri_Write(GF_Box *s, GF_BitStream *bs)
679 {
680 	//	GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s;
681 	GF_Err e = gf_isom_box_write_header(s, bs);
682 	if (e) return e;
683 	return GF_OK;
684 }
685 
mdri_Size(GF_Box * s)686 GF_Err mdri_Size(GF_Box *s)
687 {
688 	GF_Err e;
689 	//	GF_OMADRMMutableInformationBox *ptr = (GF_OMADRMMutableInformationBox *)s;
690 	if (!s) return GF_BAD_PARAM;
691 	e = gf_isom_box_get_size(s);
692 	if (e) return e;
693 
694 	return GF_OK;
695 }
696 #endif /*GPAC_DISABLE_ISOM_WRITE*/
697 
698 
699 /* OMADRMTransactionTracking Box */
odtt_New()700 GF_Box *odtt_New()
701 {
702 	ISOM_DECL_BOX_ALLOC(GF_OMADRMTransactionTrackingBox, GF_ISOM_BOX_TYPE_ODTT);
703 	gf_isom_full_box_init((GF_Box *)tmp);
704 	return (GF_Box *)tmp;
705 }
706 
odtt_del(GF_Box * s)707 void odtt_del(GF_Box *s)
708 {
709 	GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s;
710 	gf_free(ptr);
711 }
712 
odtt_Read(GF_Box * s,GF_BitStream * bs)713 GF_Err odtt_Read(GF_Box *s, GF_BitStream *bs)
714 {
715 	GF_Err e;
716 	GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox *)s;
717 	if (ptr == NULL) return GF_BAD_PARAM;
718 	e = gf_isom_full_box_read(s, bs);
719 	if (e) return e;
720 	gf_bs_read_data(bs, ptr->TransactionID, 16);
721 	ptr->size -= 16;
722 	return GF_OK;
723 }
724 
725 #ifndef GPAC_DISABLE_ISOM_WRITE
odtt_Write(GF_Box * s,GF_BitStream * bs)726 GF_Err odtt_Write(GF_Box *s, GF_BitStream *bs)
727 {
728 	GF_Err e;
729 	GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s;
730 	if (!s) return GF_BAD_PARAM;
731 	e = gf_isom_full_box_write(s, bs);
732 	if (e) return e;
733 	gf_bs_write_data(bs, ptr->TransactionID, 16);
734 	return GF_OK;
735 }
736 
odtt_Size(GF_Box * s)737 GF_Err odtt_Size(GF_Box *s)
738 {
739 	GF_Err e;
740 	if (!s) return GF_BAD_PARAM;
741 	e = gf_isom_full_box_get_size(s);
742 	if (e) return e;
743 	s->size += 16;
744 	return GF_OK;
745 }
746 #endif /*GPAC_DISABLE_ISOM_WRITE*/
747 
748 
749 
750 /* OMADRMRightsObject Box */
odrb_New()751 GF_Box *odrb_New()
752 {
753 	ISOM_DECL_BOX_ALLOC(GF_OMADRMRightsObjectBox, GF_ISOM_BOX_TYPE_ODRB);
754 	gf_isom_full_box_init((GF_Box *)tmp);
755 	return (GF_Box *)tmp;
756 }
757 
odrb_del(GF_Box * s)758 void odrb_del(GF_Box *s)
759 {
760 	GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox*)s;
761 	if (ptr->oma_ro) gf_free(ptr->oma_ro);
762 	gf_free(ptr);
763 }
764 
odrb_Read(GF_Box * s,GF_BitStream * bs)765 GF_Err odrb_Read(GF_Box *s, GF_BitStream *bs)
766 {
767 	GF_Err e;
768 	GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
769 	if (ptr == NULL) return GF_BAD_PARAM;
770 	e = gf_isom_full_box_read(s, bs);
771 	if (e) return e;
772 	ptr->oma_ro_size = (u32)ptr->size;
773 	ptr->oma_ro = (char*)gf_malloc(sizeof(char)*ptr->oma_ro_size);
774 	gf_bs_read_data(bs, ptr->oma_ro, ptr->oma_ro_size);
775 	ptr->size = 0;
776 	return GF_OK;
777 }
778 
779 #ifndef GPAC_DISABLE_ISOM_WRITE
odrb_Write(GF_Box * s,GF_BitStream * bs)780 GF_Err odrb_Write(GF_Box *s, GF_BitStream *bs)
781 {
782 	GF_Err e;
783 	GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
784 	if (!s) return GF_BAD_PARAM;
785 	e = gf_isom_full_box_write(s, bs);
786 	if (e) return e;
787 	gf_bs_write_data(bs, ptr->oma_ro, ptr->oma_ro_size);
788 	return GF_OK;
789 }
790 
odrb_Size(GF_Box * s)791 GF_Err odrb_Size(GF_Box *s)
792 {
793 	GF_Err e;
794 	GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
795 	if (!s) return GF_BAD_PARAM;
796 	e = gf_isom_full_box_get_size(s);
797 	if (e) return e;
798 	s->size += ptr->oma_ro_size;
799 	return GF_OK;
800 }
801 #endif /*GPAC_DISABLE_ISOM_WRITE*/
802 
803 
804 
805 
806 /* OMADRMKMS Box */
odkm_New()807 GF_Box *odkm_New()
808 {
809 	ISOM_DECL_BOX_ALLOC(GF_OMADRMKMSBox, GF_ISOM_BOX_TYPE_ODKM);
810 	gf_isom_full_box_init((GF_Box *)tmp);
811 	return (GF_Box *)tmp;
812 }
813 
odkm_del(GF_Box * s)814 void odkm_del(GF_Box *s)
815 {
816 	GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
817 	if (ptr->hdr) gf_isom_box_del((GF_Box*)ptr->hdr);
818 	if (ptr->fmt) gf_isom_box_del((GF_Box*)ptr->fmt);
819 	gf_free(ptr);
820 }
821 
odkm_Add(GF_Box * s,GF_Box * a)822 GF_Err odkm_Add(GF_Box *s, GF_Box *a)
823 {
824 	GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
825 	switch (a->type) {
826 	case GF_ISOM_BOX_TYPE_OHDR:
827 		if (ptr->hdr) gf_isom_box_del((GF_Box*)ptr->hdr);
828 		ptr->hdr = (GF_OMADRMCommonHeaderBox *)a;
829 		return GF_OK;
830 	case GF_ISOM_BOX_TYPE_ODAF:
831 		if (ptr->fmt) gf_isom_box_del((GF_Box*)ptr->fmt);
832 		ptr->fmt = (GF_OMADRMAUFormatBox*)a;
833 		return GF_OK;
834 	default:
835 		gf_isom_box_del(a);
836 		return GF_OK;
837 	}
838 }
839 
odkm_Read(GF_Box * s,GF_BitStream * bs)840 GF_Err odkm_Read(GF_Box *s, GF_BitStream *bs)
841 {
842 	GF_Err e;
843 	if (s == NULL) return GF_BAD_PARAM;
844 	e = gf_isom_full_box_read(s, bs);
845 	if (e) return e;
846 	return gf_isom_read_box_list(s, bs, odkm_Add);
847 }
848 
849 #ifndef GPAC_DISABLE_ISOM_WRITE
odkm_Write(GF_Box * s,GF_BitStream * bs)850 GF_Err odkm_Write(GF_Box *s, GF_BitStream *bs)
851 {
852 	GF_Err e;
853 	GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
854 	if (!s) return GF_BAD_PARAM;
855 	e = gf_isom_full_box_write(s, bs);
856 	if (e) return e;
857 	if (ptr->hdr) {
858 		e = gf_isom_box_write((GF_Box*)ptr->hdr, bs);
859 		if (e) return e;
860 	}
861 	if (ptr->fmt) {
862 		e = gf_isom_box_write((GF_Box*)ptr->fmt, bs);
863 		if (e) return e;
864 	}
865 	return GF_OK;
866 }
867 
odkm_Size(GF_Box * s)868 GF_Err odkm_Size(GF_Box *s)
869 {
870 	GF_Err e;
871 	GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
872 	if (!s) return GF_BAD_PARAM;
873 	e = gf_isom_full_box_get_size(s);
874 	if (e) return e;
875 	if (ptr->hdr) {
876 		e = gf_isom_box_size((GF_Box*)ptr->hdr);
877 		if (e) return e;
878 		ptr->size += ptr->hdr->size;
879 	}
880 	if (ptr->fmt) {
881 		e = gf_isom_box_size((GF_Box*)ptr->fmt);
882 		if (e) return e;
883 		ptr->size += ptr->fmt->size;
884 	}
885 	return GF_OK;
886 }
887 #endif /*GPAC_DISABLE_ISOM_WRITE*/
888 
889 
890 
891 
pssh_New()892 GF_Box *pssh_New()
893 {
894 	ISOM_DECL_BOX_ALLOC(GF_ProtectionSystemHeaderBox, GF_ISOM_BOX_TYPE_PSSH);
895 	return (GF_Box *)tmp;
896 }
897 
pssh_del(GF_Box * s)898 void pssh_del(GF_Box *s)
899 {
900 	GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*)s;
901 	if (ptr == NULL) return;
902 	if (ptr->private_data) gf_free(ptr->private_data);
903 	if (ptr->KIDs) gf_free(ptr->KIDs);
904 	gf_free(ptr);
905 }
906 
pssh_Read(GF_Box * s,GF_BitStream * bs)907 GF_Err pssh_Read(GF_Box *s, GF_BitStream *bs)
908 {
909 	GF_Err e;
910 	GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *)s;
911 
912 	e = gf_isom_full_box_read(s, bs);
913 	if (e) return e;
914 
915 	gf_bs_read_data(bs, (char *)ptr->SystemID, 16);
916 	ptr->size -= 16;
917 	if (ptr->version > 0) {
918 		ptr->KID_count = gf_bs_read_u32(bs);
919 		ptr->size -= 4;
920 		if (ptr->KID_count) {
921 			u32 i;
922 			ptr->KIDs = gf_malloc(ptr->KID_count * sizeof(bin128));
923 			for (i = 0; i<ptr->KID_count; i++) {
924 				gf_bs_read_data(bs, (char *)ptr->KIDs[i], 16);
925 				ptr->size -= 16;
926 			}
927 		}
928 	}
929 	ptr->private_data_size = gf_bs_read_u32(bs);
930 	ptr->size -= 4;
931 	if (ptr->private_data_size) {
932 		ptr->private_data = gf_malloc(sizeof(char)*ptr->private_data_size);
933 		gf_bs_read_data(bs, (char *)ptr->private_data, ptr->private_data_size);
934 		ptr->size -= ptr->private_data_size;
935 	}
936 	return GF_OK;
937 }
938 
939 #ifndef GPAC_DISABLE_ISOM_WRITE
940 
pssh_Write(GF_Box * s,GF_BitStream * bs)941 GF_Err pssh_Write(GF_Box *s, GF_BitStream *bs)
942 {
943 	GF_Err e;
944 	GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *)s;
945 	if (!s) return GF_BAD_PARAM;
946 	e = gf_isom_full_box_write(s, bs);
947 	if (e) return e;
948 
949 	gf_bs_write_data(bs, (char *)ptr->SystemID, 16);
950 	if (ptr->version > 0) {
951 		u32 i;
952 		gf_bs_write_u32(bs, ptr->KID_count);
953 		for (i = 0; i<ptr->KID_count; i++)
954 			gf_bs_write_data(bs, (char *)ptr->KIDs[i], 16);
955 	}
956 	if (ptr->private_data) {
957 		gf_bs_write_u32(bs, ptr->private_data_size);
958 		gf_bs_write_data(bs, (char *)ptr->private_data, ptr->private_data_size);
959 	}
960 	else
961 		gf_bs_write_u32(bs, 0);
962 	return GF_OK;
963 }
964 
pssh_Size(GF_Box * s)965 GF_Err pssh_Size(GF_Box *s)
966 {
967 	GF_Err e;
968 	GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*)s;
969 
970 	if (ptr->KID_count && !ptr->version) {
971 		ptr->version = 1;
972 	}
973 
974 	e = gf_isom_full_box_get_size(s);
975 	if (e) return e;
976 
977 	ptr->size += 16;
978 	if (ptr->version) ptr->size += 4 + 16 * ptr->KID_count;
979 	ptr->size += 4 + (ptr->private_data ? ptr->private_data_size : 0);
980 	return GF_OK;
981 }
982 #endif //GPAC_DISABLE_ISOM_WRITE
983 
984 
tenc_New()985 GF_Box *tenc_New()
986 {
987 	ISOM_DECL_BOX_ALLOC(GF_TrackEncryptionBox, GF_ISOM_BOX_TYPE_TENC);
988 	return (GF_Box *)tmp;
989 }
990 
tenc_del(GF_Box * s)991 void tenc_del(GF_Box *s)
992 {
993 	gf_free(s);
994 }
995 
tenc_Read(GF_Box * s,GF_BitStream * bs)996 GF_Err tenc_Read(GF_Box *s, GF_BitStream *bs)
997 {
998 	GF_Err e;
999 	GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*)s;
1000 
1001 	e = gf_isom_full_box_read(s, bs);
1002 	if (e) return e;
1003 
1004 	gf_bs_read_u8(bs); //reserved
1005 	if (!ptr->version) {
1006 		gf_bs_read_u8(bs); //reserved
1007 	}
1008 	else {
1009 		ptr->crypt_byte_block = gf_bs_read_int(bs, 4);
1010 		ptr->skip_byte_block = gf_bs_read_int(bs, 4);
1011 	}
1012 	ptr->isProtected = gf_bs_read_u8(bs);
1013 	ptr->Per_Sample_IV_Size = gf_bs_read_u8(bs);
1014 	gf_bs_read_data(bs, (char *)ptr->KID, 16);
1015 	ptr->size -= 20;
1016 	if ((ptr->isProtected == 1) && !ptr->Per_Sample_IV_Size) {
1017 		ptr->constant_IV_size = gf_bs_read_u8(bs);
1018 		gf_bs_read_data(bs, (char *)ptr->constant_IV, ptr->constant_IV_size);
1019 		ptr->size -= 1 + ptr->constant_IV_size;
1020 	}
1021 	return GF_OK;
1022 }
1023 
1024 #ifndef GPAC_DISABLE_ISOM_WRITE
1025 
tenc_Write(GF_Box * s,GF_BitStream * bs)1026 GF_Err tenc_Write(GF_Box *s, GF_BitStream *bs)
1027 {
1028 	GF_Err e;
1029 	GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox *)s;
1030 	if (!s) return GF_BAD_PARAM;
1031 	e = gf_isom_full_box_write(s, bs);
1032 	if (e) return e;
1033 
1034 	gf_bs_write_u8(bs, 0x0); //reserved
1035 	if (!ptr->version) {
1036 		gf_bs_write_u8(bs, 0x0); //reserved
1037 	}
1038 	else {
1039 		gf_bs_write_int(bs, ptr->crypt_byte_block, 4);
1040 		gf_bs_write_int(bs, ptr->skip_byte_block, 4);
1041 	}
1042 	gf_bs_write_u8(bs, ptr->isProtected);
1043 	gf_bs_write_u8(bs, ptr->Per_Sample_IV_Size);
1044 	gf_bs_write_data(bs, (char *)ptr->KID, 16);
1045 	if ((ptr->isProtected == 1) && !ptr->Per_Sample_IV_Size) {
1046 		gf_bs_write_u8(bs, ptr->constant_IV_size);
1047 		gf_bs_write_data(bs, (char *)ptr->constant_IV, ptr->constant_IV_size);
1048 	}
1049 	return GF_OK;
1050 }
1051 
tenc_Size(GF_Box * s)1052 GF_Err tenc_Size(GF_Box *s)
1053 {
1054 	GF_Err e;
1055 	GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*)s;
1056 	e = gf_isom_full_box_get_size(s);
1057 	if (e) return e;
1058 	ptr->size += 20;
1059 	if ((ptr->isProtected == 1) && !ptr->Per_Sample_IV_Size) {
1060 		ptr->size += 1 + ptr->constant_IV_size;
1061 	}
1062 	return GF_OK;
1063 }
1064 #endif //GPAC_DISABLE_ISOM_WRITE
1065 
piff_tenc_New()1066 GF_Box *piff_tenc_New()
1067 {
1068 	ISOM_DECL_BOX_ALLOC(GF_PIFFTrackEncryptionBox, GF_ISOM_BOX_TYPE_UUID);
1069 	tmp->internal_4cc = GF_ISOM_BOX_UUID_TENC;
1070 	return (GF_Box *)tmp;
1071 }
1072 
piff_tenc_del(GF_Box * s)1073 void piff_tenc_del(GF_Box *s)
1074 {
1075 	gf_free(s);
1076 }
1077 
piff_tenc_Read(GF_Box * s,GF_BitStream * bs)1078 GF_Err piff_tenc_Read(GF_Box *s, GF_BitStream *bs)
1079 {
1080 	GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*)s;
1081 
1082 	if (ptr->size<4) return GF_ISOM_INVALID_FILE;
1083 	ptr->version = gf_bs_read_u8(bs);
1084 	ptr->flags = gf_bs_read_u24(bs);
1085 	ptr->size -= 4;
1086 
1087 	ptr->AlgorithmID = gf_bs_read_int(bs, 24);
1088 	ptr->IV_size = gf_bs_read_u8(bs);
1089 	gf_bs_read_data(bs, (char *)ptr->KID, 16);
1090 	ptr->size -= 20;
1091 	return GF_OK;
1092 }
1093 
1094 #ifndef GPAC_DISABLE_ISOM_WRITE
1095 
piff_tenc_Write(GF_Box * s,GF_BitStream * bs)1096 GF_Err piff_tenc_Write(GF_Box *s, GF_BitStream *bs)
1097 {
1098 	GF_Err e;
1099 	GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox *)s;
1100 	if (!s) return GF_BAD_PARAM;
1101 
1102 	e = gf_isom_box_write_header(s, bs);
1103 	if (e) return e;
1104 	gf_bs_write_u8(bs, ptr->version);
1105 	gf_bs_write_u24(bs, ptr->flags);
1106 
1107 	gf_bs_write_int(bs, ptr->AlgorithmID, 24);
1108 	gf_bs_write_u8(bs, ptr->IV_size);
1109 	gf_bs_write_data(bs, (char *)ptr->KID, 16);
1110 	return GF_OK;
1111 }
1112 
piff_tenc_Size(GF_Box * s)1113 GF_Err piff_tenc_Size(GF_Box *s)
1114 {
1115 	GF_Err e;
1116 	GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*)s;
1117 	e = gf_isom_box_get_size(s);
1118 	if (e) return e;
1119 	ptr->size += 24;
1120 	return GF_OK;
1121 }
1122 #endif //GPAC_DISABLE_ISOM_WRITE
1123 
1124 
piff_psec_New()1125 GF_Box *piff_psec_New()
1126 {
1127 	ISOM_DECL_BOX_ALLOC(GF_PIFFSampleEncryptionBox, GF_ISOM_BOX_TYPE_UUID);
1128 	tmp->internal_4cc = GF_ISOM_BOX_UUID_PSEC;
1129 	return (GF_Box *)tmp;
1130 }
1131 
piff_psec_del(GF_Box * s)1132 void piff_psec_del(GF_Box *s)
1133 {
1134 	GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox *)s;
1135 	while (gf_list_count(ptr->samp_aux_info)) {
1136 		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, 0);
1137 		if (sai) gf_isom_cenc_samp_aux_info_del(sai);
1138 		gf_list_rem(ptr->samp_aux_info, 0);
1139 	}
1140 	if (ptr->samp_aux_info) gf_list_del(ptr->samp_aux_info);
1141 	gf_free(s);
1142 }
1143 
1144 
piff_psec_Read(GF_Box * s,GF_BitStream * bs)1145 GF_Err piff_psec_Read(GF_Box *s, GF_BitStream *bs)
1146 {
1147 	u32 sample_count, i, j;
1148 	GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox *)s;
1149 	if (ptr->size<4) return GF_ISOM_INVALID_FILE;
1150 	ptr->version = gf_bs_read_u8(bs);
1151 	ptr->flags = gf_bs_read_u24(bs);
1152 	ptr->size -= 4;
1153 
1154 	if (ptr->flags & 1) {
1155 		ptr->AlgorithmID = gf_bs_read_int(bs, 24);
1156 		ptr->IV_size = gf_bs_read_u8(bs);
1157 		gf_bs_read_data(bs, (char *)ptr->KID, 16);
1158 		ptr->size -= 20;
1159 	}
1160 	if (ptr->IV_size == 0)
1161 		ptr->IV_size = 8; //default to 8
1162 
1163 	sample_count = gf_bs_read_u32(bs);
1164 	ptr->size -= 4;
1165 	if (ptr->IV_size != 8 && ptr->IV_size != 16) {
1166 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] PIFF PSEC box incorrect IV size: %u - shall be 8 or 16\n", ptr->IV_size));
1167 		return GF_BAD_PARAM;
1168 	}
1169 
1170 	ptr->samp_aux_info = gf_list_new();
1171 	for (i = 0; i<sample_count; ++i) {
1172 		GF_CENCSampleAuxInfo *sai;
1173 		GF_SAFEALLOC(sai, GF_CENCSampleAuxInfo);
1174 		if (!sai) return GF_OUT_OF_MEM;
1175 
1176 		sai->IV_size = ptr->IV_size;
1177 		gf_bs_read_data(bs, (char *)sai->IV, ptr->IV_size);
1178 		ptr->size -= ptr->IV_size;
1179 		if (ptr->flags & 2) {
1180 			sai->subsample_count = gf_bs_read_u16(bs);
1181 			sai->subsamples = gf_malloc(sai->subsample_count * sizeof(GF_CENCSubSampleEntry));
1182 			for (j = 0; j < sai->subsample_count; ++j) {
1183 				sai->subsamples[j].bytes_clear_data = gf_bs_read_u16(bs);
1184 				sai->subsamples[j].bytes_encrypted_data = gf_bs_read_u32(bs);
1185 			}
1186 			ptr->size -= 2 + sai->subsample_count * 6;
1187 		}
1188 		gf_list_add(ptr->samp_aux_info, sai);
1189 	}
1190 
1191 	ptr->bs_offset = gf_bs_get_position(bs);
1192 	assert(ptr->size == 0);
1193 	return GF_OK;
1194 }
1195 
1196 #ifndef GPAC_DISABLE_ISOM_WRITE
1197 
store_senc_info(GF_SampleEncryptionBox * ptr,GF_BitStream * bs)1198 GF_Err store_senc_info(GF_SampleEncryptionBox *ptr, GF_BitStream *bs)
1199 {
1200 	GF_Err e;
1201 	u64 pos;
1202 	if (!ptr->cenc_saio) return GF_OK;
1203 
1204 	pos = gf_bs_get_position(bs);
1205 	if (pos>0xFFFFFFFFULL) {
1206 		GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] \"senc\" offset larger than 32-bits , \"saio\" box version must be 1 .\n"));
1207 	}
1208 	e = gf_bs_seek(bs, ptr->cenc_saio->offset_first_offset_field);
1209 	if (e) return e;
1210 	//force using version 1 for saio box i.e offset has 64 bits
1211 #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
1212 	if (ptr->traf) {
1213 		gf_bs_write_u64(bs, pos - ptr->traf->moof_start_in_bs);
1214 	}
1215 	else
1216 #endif
1217 	{
1218 		gf_bs_write_u64(bs, pos);
1219 	}
1220 	return gf_bs_seek(bs, pos);
1221 }
1222 
piff_psec_Write(GF_Box * s,GF_BitStream * bs)1223 GF_Err piff_psec_Write(GF_Box *s, GF_BitStream *bs)
1224 {
1225 	GF_Err e;
1226 	u32 sample_count;
1227 	GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox *)s;
1228 	if (!s) return GF_BAD_PARAM;
1229 
1230 	e = gf_isom_box_write_header(s, bs);
1231 	if (e) return e;
1232 	gf_bs_write_u8(bs, ptr->version);
1233 	gf_bs_write_u24(bs, ptr->flags);
1234 
1235 	if (ptr->flags & 1) {
1236 		gf_bs_write_int(bs, ptr->AlgorithmID, 24);
1237 		gf_bs_write_u8(bs, ptr->IV_size);
1238 		gf_bs_write_data(bs, (char *)ptr->KID, 16);
1239 	}
1240 	sample_count = gf_list_count(ptr->samp_aux_info);
1241 	gf_bs_write_u32(bs, sample_count);
1242 	if (sample_count) {
1243 		u32 i, j;
1244 		e = store_senc_info((GF_SampleEncryptionBox *)ptr, bs);
1245 		if (e) return e;
1246 
1247 		for (i = 0; i < sample_count; i++) {
1248 			GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1249 			if (!sai->IV_size) continue;
1250 			gf_bs_write_data(bs, (char *)sai->IV, sai->IV_size);
1251 			gf_bs_write_u16(bs, sai->subsample_count);
1252 			for (j = 0; j < sai->subsample_count; j++) {
1253 				gf_bs_write_u16(bs, sai->subsamples[j].bytes_clear_data);
1254 				gf_bs_write_u32(bs, sai->subsamples[j].bytes_encrypted_data);
1255 			}
1256 		}
1257 	}
1258 	return GF_OK;
1259 }
1260 
piff_psec_Size(GF_Box * s)1261 GF_Err piff_psec_Size(GF_Box *s)
1262 {
1263 	u32 i, sample_count;
1264 	GF_Err e;
1265 	GF_PIFFSampleEncryptionBox *ptr = (GF_PIFFSampleEncryptionBox*)s;
1266 	e = gf_isom_box_get_size(s);
1267 	if (e) return e;
1268 	ptr->size += 4;
1269 	if (ptr->flags & 1) {
1270 		ptr->size += 20;
1271 	}
1272 	ptr->size += 4;
1273 	sample_count = gf_list_count(ptr->samp_aux_info);
1274 	if (sample_count) {
1275 		for (i = 0; i < sample_count; i++) {
1276 			GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1277 			if (!sai->IV_size) continue;
1278 			ptr->size += 18 + 6 * sai->subsample_count;
1279 		}
1280 	}
1281 	return GF_OK;
1282 }
1283 #endif //GPAC_DISABLE_ISOM_WRITE
1284 
1285 
piff_pssh_New()1286 GF_Box *piff_pssh_New()
1287 {
1288 	ISOM_DECL_BOX_ALLOC(GF_PIFFProtectionSystemHeaderBox, GF_ISOM_BOX_TYPE_UUID);
1289 	tmp->internal_4cc = GF_ISOM_BOX_UUID_PSSH;
1290 	return (GF_Box *)tmp;
1291 }
1292 
piff_pssh_del(GF_Box * s)1293 void piff_pssh_del(GF_Box *s)
1294 {
1295 	gf_free(s);
1296 }
1297 
piff_pssh_Read(GF_Box * s,GF_BitStream * bs)1298 GF_Err piff_pssh_Read(GF_Box *s, GF_BitStream *bs)
1299 {
1300 	GF_Err e;
1301 	GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s;
1302 
1303 	e = gf_isom_full_box_read(s, bs);
1304 	if (e) return e;
1305 
1306 	gf_bs_read_data(bs, (char *)ptr->SystemID, 16);
1307 	ptr->private_data_size = gf_bs_read_u32(bs);
1308 	ptr->size -= 20;
1309 	ptr->private_data = gf_malloc(sizeof(char)*ptr->private_data_size);
1310 	gf_bs_read_data(bs, (char *)ptr->private_data, ptr->private_data_size);
1311 	ptr->size -= ptr->private_data_size;
1312 	return GF_OK;
1313 }
1314 
1315 #ifndef GPAC_DISABLE_ISOM_WRITE
1316 
piff_pssh_Write(GF_Box * s,GF_BitStream * bs)1317 GF_Err piff_pssh_Write(GF_Box *s, GF_BitStream *bs)
1318 {
1319 	GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox *)s;
1320 	GF_Err e = gf_isom_full_box_write(s, bs);
1321 	if (e) return e;
1322 
1323 	gf_bs_write_data(bs, (char *)ptr->SystemID, 16);
1324 	gf_bs_write_u32(bs, ptr->private_data_size);
1325 	gf_bs_write_data(bs, (char *)ptr->private_data, ptr->private_data_size);
1326 	return GF_OK;
1327 }
1328 
piff_pssh_Size(GF_Box * s)1329 GF_Err piff_pssh_Size(GF_Box *s)
1330 {
1331 	GF_Err e;
1332 	GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s;
1333 	e = gf_isom_box_get_size(s);
1334 	if (e) return e;
1335 	ptr->size += 24 + ptr->private_data_size;
1336 	return GF_OK;
1337 }
1338 #endif //GPAC_DISABLE_ISOM_WRITE
1339 
senc_New()1340 GF_Box *senc_New()
1341 {
1342 	ISOM_DECL_BOX_ALLOC(GF_SampleEncryptionBox, GF_ISOM_BOX_TYPE_SENC);
1343 	return (GF_Box *)tmp;
1344 }
1345 
senc_del(GF_Box * s)1346 void senc_del(GF_Box *s)
1347 {
1348 	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
1349 	while (gf_list_count(ptr->samp_aux_info)) {
1350 		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, 0);
1351 		if (sai) gf_isom_cenc_samp_aux_info_del(sai);
1352 		gf_list_rem(ptr->samp_aux_info, 0);
1353 	}
1354 	if (ptr->samp_aux_info) gf_list_del(ptr->samp_aux_info);
1355 	gf_free(s);
1356 }
1357 
1358 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
senc_Parse(GF_BitStream * bs,GF_TrackBox * trak,GF_TrackFragmentBox * traf,GF_SampleEncryptionBox * ptr)1359 GF_Err senc_Parse(GF_BitStream *bs, GF_TrackBox *trak, GF_TrackFragmentBox *traf, GF_SampleEncryptionBox *ptr)
1360 #else
1361 GF_Err senc_Parse(GF_BitStream *bs, GF_TrackBox *trak, void *traf, GF_SampleEncryptionBox *ptr)
1362 #endif
1363 {
1364 	GF_Err e;
1365 	u32 i, j, count;
1366 	u64 pos = gf_bs_get_position(bs);
1367 
1368 #ifdef	GPAC_DISABLE_ISOM_FRAGMENTS
1369 	if (!traf)
1370 		return GF_BAD_PARAM;
1371 #endif
1372 
1373 	gf_bs_seek(bs, ptr->bs_offset);
1374 
1375 	count = gf_bs_read_u32(bs);
1376 	if (!ptr->samp_aux_info) ptr->samp_aux_info = gf_list_new();
1377 	for (i = 0; i<count; i++) {
1378 		u32 is_encrypted;
1379 		u32 samp_count;
1380 		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_malloc(sizeof(GF_CENCSampleAuxInfo));
1381 		memset(sai, 0, sizeof(GF_CENCSampleAuxInfo));
1382 
1383 		samp_count = i + 1;
1384 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
1385 		if (trak) samp_count += trak->sample_count_at_seg_start;
1386 #endif
1387 
1388 		e = gf_isom_get_sample_cenc_info_ex(trak, traf, samp_count, &is_encrypted, &sai->IV_size, NULL, NULL, NULL, NULL, NULL);
1389 		if (e) {
1390 			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isobmf] could not get cenc info for sample %d: %s\n", samp_count, gf_error_to_string(e)));
1391 			return e;
1392 		}
1393 		if (is_encrypted) {
1394 			gf_bs_read_data(bs, (char *)sai->IV, sai->IV_size);
1395 			if (ptr->flags & 0x00000002) {
1396 				sai->subsample_count = gf_bs_read_u16(bs);
1397 				sai->subsamples = (GF_CENCSubSampleEntry *)gf_malloc(sai->subsample_count * sizeof(GF_CENCSubSampleEntry));
1398 				for (j = 0; j < sai->subsample_count; j++) {
1399 					sai->subsamples[j].bytes_clear_data = gf_bs_read_u16(bs);
1400 					sai->subsamples[j].bytes_encrypted_data = gf_bs_read_u32(bs);
1401 				}
1402 			}
1403 		}
1404 		gf_list_add(ptr->samp_aux_info, sai);
1405 	}
1406 	gf_bs_seek(bs, pos);
1407 	return GF_OK;
1408 }
1409 
1410 
senc_Read(GF_Box * s,GF_BitStream * bs)1411 GF_Err senc_Read(GF_Box *s, GF_BitStream *bs)
1412 {
1413 	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
1414 	//WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
1415 	ptr->version = gf_bs_read_u8(bs);
1416 	ptr->flags = gf_bs_read_u24(bs);
1417 	ptr->size -= 4;
1418 
1419 	ptr->bs_offset = gf_bs_get_position(bs);
1420 	gf_bs_skip_bytes(bs, ptr->size);
1421 	ptr->size = 0;
1422 	return GF_OK;
1423 }
1424 
1425 #ifndef GPAC_DISABLE_ISOM_WRITE
1426 
1427 
senc_Write(GF_Box * s,GF_BitStream * bs)1428 GF_Err senc_Write(GF_Box *s, GF_BitStream *bs)
1429 {
1430 	GF_Err e;
1431 	u32 sample_count;
1432 	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
1433 	e = gf_isom_box_write_header(s, bs);
1434 	if (e) return e;
1435 	//WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
1436 	gf_bs_write_u8(bs, ptr->version);
1437 	gf_bs_write_u24(bs, ptr->flags);
1438 
1439 	sample_count = gf_list_count(ptr->samp_aux_info);
1440 	gf_bs_write_u32(bs, sample_count);
1441 	if (sample_count) {
1442 		u32 i, j;
1443 
1444 		e = store_senc_info(ptr, bs);
1445 		if (e) return e;
1446 
1447 		for (i = 0; i < sample_count; i++) {
1448 			GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1449 			//for cbcs scheme, IV_size is 0, constant IV shall be used. It is written in tenc box rather than in sai
1450 			if (sai->IV_size)
1451 				gf_bs_write_data(bs, (char *)sai->IV, sai->IV_size);
1452 			if (ptr->flags & 0x00000002) {
1453 				gf_bs_write_u16(bs, sai->subsample_count);
1454 				for (j = 0; j < sai->subsample_count; j++) {
1455 					gf_bs_write_u16(bs, sai->subsamples[j].bytes_clear_data);
1456 					gf_bs_write_u32(bs, sai->subsamples[j].bytes_encrypted_data);
1457 				}
1458 			}
1459 		}
1460 	}
1461 	return GF_OK;
1462 }
1463 
senc_Size(GF_Box * s)1464 GF_Err senc_Size(GF_Box *s)
1465 {
1466 	GF_Err e;
1467 	u32 sample_count;
1468 	u32 i;
1469 	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox*)s;
1470 	//WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
1471 	e = gf_isom_box_get_size(s);
1472 	if (e) return e;
1473 	ptr->size += 4;
1474 
1475 	ptr->size += 4;
1476 	sample_count = gf_list_count(ptr->samp_aux_info);
1477 	if (sample_count) {
1478 		for (i = 0; i < sample_count; i++) {
1479 			GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1480 			//if (! sai->IV_size) continue;
1481 			ptr->size += sai->IV_size;
1482 			if (ptr->flags & 0x00000002)
1483 				ptr->size += 2 + 6 * sai->subsample_count;
1484 		}
1485 	}
1486 	return GF_OK;
1487 }
1488 #endif //GPAC_DISABLE_ISOM_WRITE
1489 
adkm_New()1490 GF_Box *adkm_New()
1491 {
1492 	ISOM_DECL_BOX_ALLOC(GF_AdobeDRMKeyManagementSystemBox, GF_ISOM_BOX_TYPE_ADKM);
1493 	tmp->version = 1;
1494 	tmp->flags = 0;
1495 	return (GF_Box *)tmp;
1496 }
1497 
adkm_del(GF_Box * s)1498 void adkm_del(GF_Box *s)
1499 {
1500 	GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
1501 	if (!ptr) return;
1502 	if (ptr->header) gf_isom_box_del((GF_Box *)ptr->header);
1503 	if (ptr->au_format) gf_isom_box_del((GF_Box *)ptr->au_format);
1504 	gf_free(s);
1505 }
1506 
adkm_AddBox(GF_Box * s,GF_Box * a)1507 GF_Err adkm_AddBox(GF_Box *s, GF_Box *a)
1508 {
1509 	GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
1510 	switch (a->type) {
1511 	case GF_ISOM_BOX_TYPE_AHDR:
1512 		if (ptr->header) return GF_ISOM_INVALID_FILE;
1513 		ptr->header = (GF_AdobeDRMHeaderBox *)a;
1514 		break;
1515 	case GF_ISOM_BOX_TYPE_ADAF:
1516 		if (ptr->au_format) return GF_ISOM_INVALID_FILE;
1517 		ptr->au_format = (GF_AdobeDRMAUFormatBox *)a;
1518 		break;
1519 
1520 	default:
1521 		return gf_isom_box_add_default(s, a);
1522 	}
1523 	return GF_OK;
1524 }
1525 
adkm_Read(GF_Box * s,GF_BitStream * bs)1526 GF_Err adkm_Read(GF_Box *s, GF_BitStream *bs)
1527 {
1528 	GF_Err e;
1529 	e = gf_isom_full_box_read(s, bs);
1530 	if (e) return e;
1531 	return gf_isom_read_box_list(s, bs, adkm_AddBox);
1532 }
1533 
1534 #ifndef GPAC_DISABLE_ISOM_WRITE
adkm_Write(GF_Box * s,GF_BitStream * bs)1535 GF_Err adkm_Write(GF_Box *s, GF_BitStream *bs)
1536 {
1537 	GF_Err e;
1538 	GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
1539 	if (!s) return GF_BAD_PARAM;
1540 	e = gf_isom_full_box_write(s, bs);
1541 	if (e) return e;
1542 	//ahdr
1543 	e = gf_isom_box_write((GF_Box *)ptr->header, bs);
1544 	if (e) return e;
1545 	//adaf
1546 	e = gf_isom_box_write((GF_Box *)ptr->au_format, bs);
1547 	if (e) return e;
1548 
1549 	return GF_OK;
1550 }
1551 
adkm_Size(GF_Box * s)1552 GF_Err adkm_Size(GF_Box *s)
1553 {
1554 	GF_Err e;
1555 	GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
1556 	if (!s) return GF_BAD_PARAM;
1557 	e = gf_isom_full_box_get_size(s);
1558 	if (e) return e;
1559 	e = gf_isom_box_size((GF_Box *)ptr->header);
1560 	if (e) return e;
1561 	ptr->size += ptr->header->size;
1562 	e = gf_isom_box_size((GF_Box *)ptr->au_format);
1563 	if (e) return e;
1564 	ptr->size += ptr->au_format->size;
1565 	return GF_OK;
1566 }
1567 #endif //GPAC_DISABLE_ISOM_WRITE
1568 
ahdr_New()1569 GF_Box *ahdr_New()
1570 {
1571 	ISOM_DECL_BOX_ALLOC(GF_AdobeDRMHeaderBox, GF_ISOM_BOX_TYPE_AHDR);
1572 	tmp->version = 2;
1573 	tmp->flags = 0;
1574 	return (GF_Box *)tmp;
1575 }
1576 
ahdr_del(GF_Box * s)1577 void ahdr_del(GF_Box *s)
1578 {
1579 	GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s;
1580 	if (!ptr) return;
1581 	if (ptr->std_enc_params) gf_isom_box_del((GF_Box *)ptr->std_enc_params);
1582 	gf_free(s);
1583 }
1584 
1585 
ahdr_AddBox(GF_Box * s,GF_Box * a)1586 GF_Err ahdr_AddBox(GF_Box *s, GF_Box *a)
1587 {
1588 	GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s;
1589 	switch (a->type) {
1590 	case GF_ISOM_BOX_TYPE_APRM:
1591 		if (ptr->std_enc_params) return GF_ISOM_INVALID_FILE;
1592 		ptr->std_enc_params = (GF_AdobeStdEncryptionParamsBox *)a;
1593 		break;
1594 
1595 	default:
1596 		return gf_isom_box_add_default(s, a);
1597 	}
1598 	return GF_OK;
1599 }
1600 
ahdr_Read(GF_Box * s,GF_BitStream * bs)1601 GF_Err ahdr_Read(GF_Box *s, GF_BitStream *bs)
1602 {
1603 	GF_Err e;
1604 	e = gf_isom_full_box_read(s, bs);
1605 	if (e) return e;
1606 	return gf_isom_read_box_list(s, bs, ahdr_AddBox);
1607 }
1608 
1609 #ifndef GPAC_DISABLE_ISOM_WRITE
ahdr_Write(GF_Box * s,GF_BitStream * bs)1610 GF_Err ahdr_Write(GF_Box *s, GF_BitStream *bs)
1611 {
1612 	GF_Err e;
1613 	GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s;
1614 	if (!s) return GF_BAD_PARAM;
1615 	e = gf_isom_full_box_write(s, bs);
1616 	if (e) return e;
1617 	e = gf_isom_box_write((GF_Box *)ptr->std_enc_params, bs);
1618 	if (e) return e;
1619 
1620 	return GF_OK;
1621 }
1622 
ahdr_Size(GF_Box * s)1623 GF_Err ahdr_Size(GF_Box *s)
1624 {
1625 	GF_Err e;
1626 	GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s;
1627 	if (!s) return GF_BAD_PARAM;
1628 	e = gf_isom_full_box_get_size(s);
1629 	if (e) return e;
1630 	e = gf_isom_box_size((GF_Box *)ptr->std_enc_params);
1631 	if (e) return e;
1632 	ptr->size += ptr->std_enc_params->size;
1633 	return GF_OK;
1634 }
1635 #endif //GPAC_DISABLE_ISOM_WRITE
1636 
aprm_New()1637 GF_Box *aprm_New()
1638 {
1639 	ISOM_DECL_BOX_ALLOC(GF_AdobeStdEncryptionParamsBox, GF_ISOM_BOX_TYPE_APRM);
1640 	tmp->version = 1;
1641 	tmp->flags = 0;
1642 	return (GF_Box *)tmp;
1643 }
1644 
aprm_del(GF_Box * s)1645 void aprm_del(GF_Box *s)
1646 {
1647 	GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s;
1648 	if (!ptr) return;
1649 	if (ptr->enc_info) gf_isom_box_del((GF_Box *)ptr->enc_info);
1650 	if (ptr->key_info) gf_isom_box_del((GF_Box *)ptr->key_info);
1651 	gf_free(s);
1652 }
1653 
aprm_AddBox(GF_Box * s,GF_Box * a)1654 GF_Err aprm_AddBox(GF_Box *s, GF_Box *a)
1655 {
1656 	GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s;
1657 	switch (a->type) {
1658 	case GF_ISOM_BOX_TYPE_AEIB:
1659 		if (ptr->enc_info) return GF_ISOM_INVALID_FILE;
1660 		ptr->enc_info = (GF_AdobeEncryptionInfoBox *)a;
1661 		break;
1662 	case GF_ISOM_BOX_TYPE_AKEY:
1663 		if (ptr->key_info) return GF_ISOM_INVALID_FILE;
1664 		ptr->key_info = (GF_AdobeKeyInfoBox *)a;
1665 		break;
1666 
1667 	default:
1668 		return gf_isom_box_add_default(s, a);
1669 	}
1670 	return GF_OK;
1671 }
1672 
aprm_Read(GF_Box * s,GF_BitStream * bs)1673 GF_Err aprm_Read(GF_Box *s, GF_BitStream *bs)
1674 {
1675 	GF_Err e;
1676 	e = gf_isom_full_box_read(s, bs);
1677 	if (e) return e;
1678 	return gf_isom_read_box_list(s, bs, aprm_AddBox);
1679 }
1680 
1681 #ifndef GPAC_DISABLE_ISOM_WRITE
aprm_Write(GF_Box * s,GF_BitStream * bs)1682 GF_Err aprm_Write(GF_Box *s, GF_BitStream *bs)
1683 {
1684 	GF_Err e;
1685 	GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s;
1686 	if (!s) return GF_BAD_PARAM;
1687 	e = gf_isom_full_box_write(s, bs);
1688 	if (e) return e;
1689 	//aeib
1690 	e = gf_isom_box_write((GF_Box *)ptr->enc_info, bs);
1691 	if (e) return e;
1692 	//akey
1693 	e = gf_isom_box_write((GF_Box *)ptr->key_info, bs);
1694 	if (e) return e;
1695 
1696 	return GF_OK;
1697 }
1698 
aprm_Size(GF_Box * s)1699 GF_Err aprm_Size(GF_Box *s)
1700 {
1701 	GF_Err e;
1702 	GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s;
1703 	if (!s) return GF_BAD_PARAM;
1704 	e = gf_isom_full_box_get_size(s);
1705 	if (e) return e;
1706 	e = gf_isom_box_size((GF_Box *)ptr->enc_info);
1707 	if (e) return e;
1708 	ptr->size += ptr->enc_info->size;
1709 	e = gf_isom_box_size((GF_Box *)ptr->key_info);
1710 	if (e) return e;
1711 	ptr->size += ptr->key_info->size;
1712 	return GF_OK;
1713 }
1714 #endif //GPAC_DISABLE_ISOM_WRITE
1715 
aeib_New()1716 GF_Box *aeib_New()
1717 {
1718 	ISOM_DECL_BOX_ALLOC(GF_AdobeEncryptionInfoBox, GF_ISOM_BOX_TYPE_AEIB);
1719 	tmp->version = 1;
1720 	tmp->flags = 0;
1721 	return (GF_Box *)tmp;
1722 }
1723 
aeib_del(GF_Box * s)1724 void aeib_del(GF_Box *s)
1725 {
1726 	GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s;
1727 	if (!ptr) return;
1728 	if (ptr->enc_algo) gf_free(ptr->enc_algo);
1729 	gf_free(ptr);
1730 }
1731 
aeib_Read(GF_Box * s,GF_BitStream * bs)1732 GF_Err aeib_Read(GF_Box *s, GF_BitStream *bs)
1733 {
1734 	GF_Err e;
1735 	GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s;
1736 	u32 len;
1737 
1738 	e = gf_isom_full_box_read(s, bs);
1739 	if (e) return e;
1740 
1741 	len = (u32)ptr->size - 1;
1742 	if (len) {
1743 		if (ptr->enc_algo) return GF_ISOM_INVALID_FILE;
1744 		ptr->enc_algo = (char *)gf_malloc(len * sizeof(char));
1745 		gf_bs_read_data(bs, ptr->enc_algo, len);
1746 	}
1747 	ptr->key_length = gf_bs_read_u8(bs);
1748 	ptr->size = 0;
1749 	return GF_OK;
1750 }
1751 
1752 #ifndef GPAC_DISABLE_ISOM_WRITE
1753 
aeib_Write(GF_Box * s,GF_BitStream * bs)1754 GF_Err aeib_Write(GF_Box *s, GF_BitStream *bs)
1755 {
1756 	GF_Err e;
1757 	GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox *)s;
1758 	if (!s) return GF_BAD_PARAM;
1759 	e = gf_isom_full_box_write(s, bs);
1760 	if (e) return e;
1761 	if (ptr->enc_algo) {
1762 		gf_bs_write_data(bs, (char *)ptr->enc_algo, (u32)strlen(ptr->enc_algo));
1763 		gf_bs_write_u8(bs, 0); //string end
1764 	}
1765 	gf_bs_write_u8(bs, ptr->key_length);
1766 	return GF_OK;
1767 }
1768 
aeib_Size(GF_Box * s)1769 GF_Err aeib_Size(GF_Box *s)
1770 {
1771 	GF_Err e;
1772 	GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s;
1773 	e = gf_isom_full_box_get_size(s);
1774 	if (e) return e;
1775 	if (ptr->enc_algo)
1776 		ptr->size += strlen(ptr->enc_algo) + 1;
1777 	ptr->size += 1; //KeyLength
1778 	return GF_OK;
1779 }
1780 #endif //GPAC_DISABLE_ISOM_WRITE
1781 
akey_New()1782 GF_Box *akey_New()
1783 {
1784 	ISOM_DECL_BOX_ALLOC(GF_AdobeKeyInfoBox, GF_ISOM_BOX_TYPE_AKEY);
1785 	tmp->version = 1;
1786 	tmp->flags = 0;
1787 	return (GF_Box *)tmp;
1788 }
1789 
akey_del(GF_Box * s)1790 void akey_del(GF_Box *s)
1791 {
1792 	GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s;
1793 	if (!ptr) return;
1794 	if (ptr->params) gf_isom_box_del((GF_Box *)ptr->params);
1795 	gf_free(s);
1796 }
1797 
akey_AddBox(GF_Box * s,GF_Box * a)1798 GF_Err akey_AddBox(GF_Box *s, GF_Box *a)
1799 {
1800 	GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s;
1801 	switch (a->type) {
1802 	case GF_ISOM_BOX_TYPE_FLXS:
1803 		if (ptr->params) return GF_ISOM_INVALID_FILE;
1804 		ptr->params = (GF_AdobeFlashAccessParamsBox *)a;
1805 		break;
1806 	default:
1807 		return gf_isom_box_add_default(s, a);
1808 	}
1809 	return GF_OK;
1810 }
1811 
akey_Read(GF_Box * s,GF_BitStream * bs)1812 GF_Err akey_Read(GF_Box *s, GF_BitStream *bs)
1813 {
1814 	GF_Err e;
1815 	e = gf_isom_full_box_read(s, bs);
1816 	if (e) return e;
1817 
1818 	return gf_isom_read_box_list(s, bs, akey_AddBox);
1819 }
1820 
1821 #ifndef GPAC_DISABLE_ISOM_WRITE
akey_Write(GF_Box * s,GF_BitStream * bs)1822 GF_Err akey_Write(GF_Box *s, GF_BitStream *bs)
1823 {
1824 	GF_Err e;
1825 	GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s;
1826 	if (!s) return GF_BAD_PARAM;
1827 	e = gf_isom_full_box_write(s, bs);
1828 	if (e) return e;
1829 	e = gf_isom_box_write((GF_Box *)ptr->params, bs);
1830 	if (e) return e;
1831 
1832 	return GF_OK;
1833 }
1834 
akey_Size(GF_Box * s)1835 GF_Err akey_Size(GF_Box *s)
1836 {
1837 	GF_Err e;
1838 	GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s;
1839 	if (!s) return GF_BAD_PARAM;
1840 	e = gf_isom_full_box_get_size(s);
1841 	if (e) return e;
1842 	e = gf_isom_box_size((GF_Box *)ptr->params);
1843 	if (e) return e;
1844 	ptr->size += ptr->params->size;
1845 	e = gf_isom_box_size((GF_Box *)ptr->params);
1846 	return e;
1847 }
1848 #endif //GPAC_DISABLE_ISOM_WRITE
1849 
flxs_New()1850 GF_Box *flxs_New()
1851 {
1852 	ISOM_DECL_BOX_ALLOC(GF_AdobeFlashAccessParamsBox, GF_ISOM_BOX_TYPE_FLXS);
1853 	return (GF_Box *)tmp;
1854 }
1855 
flxs_del(GF_Box * s)1856 void flxs_del(GF_Box *s)
1857 {
1858 	GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s;
1859 	if (!ptr) return;
1860 	if (ptr->metadata)
1861 		gf_free(ptr->metadata);
1862 	gf_free(ptr);
1863 }
1864 
flxs_Read(GF_Box * s,GF_BitStream * bs)1865 GF_Err flxs_Read(GF_Box *s, GF_BitStream *bs)
1866 {
1867 	GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s;
1868 	u32 len;
1869 
1870 	len = (u32)ptr->size;
1871 	if (len) {
1872 		if (ptr->metadata) return GF_ISOM_INVALID_FILE;
1873 		ptr->metadata = (char *)gf_malloc(len * sizeof(char));
1874 		gf_bs_read_data(bs, ptr->metadata, len);
1875 	}
1876 	return GF_OK;
1877 }
1878 
1879 #ifndef GPAC_DISABLE_ISOM_WRITE
1880 
flxs_Write(GF_Box * s,GF_BitStream * bs)1881 GF_Err flxs_Write(GF_Box *s, GF_BitStream *bs)
1882 {
1883 	GF_Err e;
1884 	GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox *)s;
1885 	if (!s) return GF_BAD_PARAM;
1886 	e = gf_isom_box_write_header(s, bs);
1887 	if (e) return e;
1888 	if (ptr->metadata) {
1889 		gf_bs_write_data(bs, ptr->metadata, (u32)strlen(ptr->metadata));
1890 		gf_bs_write_u8(bs, 0); //string end
1891 	}
1892 	return GF_OK;
1893 }
1894 
flxs_Size(GF_Box * s)1895 GF_Err flxs_Size(GF_Box *s)
1896 {
1897 	GF_Err e;
1898 	GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s;
1899 	e = gf_isom_box_get_size(s);
1900 	if (e) return e;
1901 	if (ptr->metadata)
1902 		ptr->size += strlen(ptr->metadata) + 1;
1903 	return GF_OK;
1904 }
1905 #endif //GPAC_DISABLE_ISOM_WRITE
1906 
adaf_New()1907 GF_Box *adaf_New()
1908 {
1909 	ISOM_DECL_BOX_ALLOC(GF_AdobeDRMAUFormatBox, GF_ISOM_BOX_TYPE_ADAF);
1910 	return (GF_Box *)tmp;
1911 }
1912 
adaf_del(GF_Box * s)1913 void adaf_del(GF_Box *s)
1914 {
1915 	gf_free(s);
1916 }
1917 
adaf_Read(GF_Box * s,GF_BitStream * bs)1918 GF_Err adaf_Read(GF_Box *s, GF_BitStream *bs)
1919 {
1920 	GF_Err e;
1921 	GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox*)s;
1922 
1923 	e = gf_isom_full_box_read(s, bs);
1924 	if (e) return e;
1925 
1926 	ptr->selective_enc = gf_bs_read_u8(bs);
1927 	gf_bs_read_u8(bs);//resersed
1928 	ptr->IV_length = gf_bs_read_u8(bs);
1929 	ptr->size -= 3;
1930 	return GF_OK;
1931 }
1932 
1933 #ifndef GPAC_DISABLE_ISOM_WRITE
1934 
adaf_Write(GF_Box * s,GF_BitStream * bs)1935 GF_Err adaf_Write(GF_Box *s, GF_BitStream *bs)
1936 {
1937 	GF_Err e;
1938 	GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox *)s;
1939 	if (!s) return GF_BAD_PARAM;
1940 	e = gf_isom_full_box_write(s, bs);
1941 	if (e) return e;
1942 
1943 	gf_bs_write_u8(bs, ptr->selective_enc);
1944 	gf_bs_write_u8(bs, 0x0);
1945 	gf_bs_write_u8(bs, ptr->IV_length);
1946 	return GF_OK;
1947 }
1948 
adaf_Size(GF_Box * s)1949 GF_Err adaf_Size(GF_Box *s)
1950 {
1951 	GF_Err e;
1952 	GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox*)s;
1953 	e = gf_isom_full_box_get_size(s);
1954 	if (e) return e;
1955 	ptr->size += 3;
1956 	return GF_OK;
1957 }
1958 #endif //GPAC_DISABLE_ISOM_WRITE
1959 
1960 
1961 #endif /*GPAC_DISABLE_ISOM*/
1962