1 /*
2  *			GPAC - Multimedia Framework C SDK
3  *
4  *			Authors: Cyril Concolato, Jean Le Feuvre
5  *			Copyright (c) Telecom ParisTech 2005-2019
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_box_new()31 GF_Box *sinf_box_new()
32 {
33 	ISOM_DECL_BOX_ALLOC(GF_ProtectionSchemeInfoBox, GF_ISOM_BOX_TYPE_SINF);
34 	return (GF_Box *)tmp;
35 }
36 
sinf_box_del(GF_Box * s)37 void sinf_box_del(GF_Box *s)
38 {
39 	gf_free(s);
40 }
41 
sinf_on_child_box(GF_Box * s,GF_Box * a)42 GF_Err sinf_on_child_box(GF_Box *s, GF_Box *a)
43 {
44 	GF_ProtectionSchemeInfoBox *ptr = (GF_ProtectionSchemeInfoBox *)s;
45 	switch (a->type) {
46 	case GF_ISOM_BOX_TYPE_FRMA:
47 		if (ptr->original_format) ERROR_ON_DUPLICATED_BOX(a, ptr)
48 		ptr->original_format = (GF_OriginalFormatBox*)a;
49 		break;
50 	case GF_ISOM_BOX_TYPE_SCHM:
51 		if (ptr->scheme_type) ERROR_ON_DUPLICATED_BOX(a, ptr)
52 		ptr->scheme_type = (GF_SchemeTypeBox*)a;
53 		break;
54 	case GF_ISOM_BOX_TYPE_SCHI:
55 		if (ptr->info) ERROR_ON_DUPLICATED_BOX(a, ptr)
56 		ptr->info = (GF_SchemeInformationBox*)a;
57 		break;
58 	}
59 	return GF_OK;
60 }
61 
sinf_box_read(GF_Box * s,GF_BitStream * bs)62 GF_Err sinf_box_read(GF_Box *s, GF_BitStream *bs)
63 {
64 	return gf_isom_box_array_read(s, bs, sinf_on_child_box);
65 }
66 
67 #ifndef GPAC_DISABLE_ISOM_WRITE
sinf_box_write(GF_Box * s,GF_BitStream * bs)68 GF_Err sinf_box_write(GF_Box *s, GF_BitStream *bs)
69 {
70 	return  gf_isom_box_write_header(s, bs);
71 }
72 
sinf_box_size(GF_Box * s)73 GF_Err sinf_box_size(GF_Box *s)
74 {
75 	u32 pos=0;
76 	GF_ProtectionSchemeInfoBox *ptr = (GF_ProtectionSchemeInfoBox *)s;
77 	gf_isom_check_position(s, (GF_Box *)ptr->original_format, &pos);
78 	gf_isom_check_position(s, (GF_Box *)ptr->scheme_type, &pos);
79 	gf_isom_check_position(s, (GF_Box *)ptr->info, &pos);
80     return GF_OK;
81 }
82 #endif /*GPAC_DISABLE_ISOM_WRITE*/
83 
84 /* OriginalFormat Box */
frma_box_new()85 GF_Box *frma_box_new()
86 {
87 	ISOM_DECL_BOX_ALLOC(GF_OriginalFormatBox, GF_ISOM_BOX_TYPE_FRMA);
88 	return (GF_Box *)tmp;
89 }
90 
frma_box_del(GF_Box * s)91 void frma_box_del(GF_Box *s)
92 {
93 	GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
94 	if (ptr == NULL) return;
95 	gf_free(ptr);
96 }
97 
frma_box_read(GF_Box * s,GF_BitStream * bs)98 GF_Err frma_box_read(GF_Box *s, GF_BitStream *bs)
99 {
100 	GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
101 	ISOM_DECREASE_SIZE(ptr, 4);
102 	ptr->data_format = gf_bs_read_u32(bs);
103 	return GF_OK;
104 }
105 
106 #ifndef GPAC_DISABLE_ISOM_WRITE
frma_box_write(GF_Box * s,GF_BitStream * bs)107 GF_Err frma_box_write(GF_Box *s, GF_BitStream *bs)
108 {
109 	GF_Err e;
110 	GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
111 	if (!s) return GF_BAD_PARAM;
112 	e = gf_isom_box_write_header(s, bs);
113 	if (e) return e;
114 	gf_bs_write_u32(bs, ptr->data_format);
115 	return GF_OK;
116 }
117 
frma_box_size(GF_Box * s)118 GF_Err frma_box_size(GF_Box *s)
119 {
120 	GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
121 	ptr->size += 4;
122 	return GF_OK;
123 }
124 #endif /*GPAC_DISABLE_ISOM_WRITE*/
125 
126 /* SchemeType Box */
schm_box_new()127 GF_Box *schm_box_new()
128 {
129 	ISOM_DECL_BOX_ALLOC(GF_SchemeTypeBox, GF_ISOM_BOX_TYPE_SCHM);
130 	return (GF_Box *)tmp;
131 }
132 
schm_box_del(GF_Box * s)133 void schm_box_del(GF_Box *s)
134 {
135 	GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
136 	if (ptr == NULL) return;
137 	if (ptr->URI) gf_free(ptr->URI);
138 	gf_free(ptr);
139 }
140 
schm_box_read(GF_Box * s,GF_BitStream * bs)141 GF_Err schm_box_read(GF_Box *s, GF_BitStream *bs)
142 {
143 	GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
144 
145 	ISOM_DECREASE_SIZE(ptr, 8);
146 	ptr->scheme_type = gf_bs_read_u32(bs);
147 	ptr->scheme_version = gf_bs_read_u32(bs);
148 
149 	if (ptr->size && (ptr->flags & 0x000001)) {
150 		u32 len = (u32) (ptr->size);
151 		ptr->URI = (char*)gf_malloc(sizeof(char)*len);
152 		if (!ptr->URI) return GF_OUT_OF_MEM;
153 		gf_bs_read_data(bs, ptr->URI, len);
154 	}
155 	return GF_OK;
156 }
157 
158 #ifndef GPAC_DISABLE_ISOM_WRITE
schm_box_write(GF_Box * s,GF_BitStream * bs)159 GF_Err schm_box_write(GF_Box *s, GF_BitStream *bs)
160 {
161 	GF_Err e;
162 	GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s;
163 	if (!s) return GF_BAD_PARAM;
164 	e = gf_isom_full_box_write(s, bs);
165 	if (e) return e;
166 	gf_bs_write_u32(bs, ptr->scheme_type);
167 	gf_bs_write_u32(bs, ptr->scheme_version);
168 	if (ptr->flags & 0x000001) {
169 		if (ptr->URI)
170 			gf_bs_write_data(bs, ptr->URI, (u32) strlen(ptr->URI)+1);
171 		else
172 			gf_bs_write_u8(bs, 0);
173 	}
174 	return GF_OK;
175 }
176 
schm_box_size(GF_Box * s)177 GF_Err schm_box_size(GF_Box *s)
178 {
179 	GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s;
180 	if (!s) return GF_BAD_PARAM;
181 	ptr->size += 8;
182 	if (ptr->flags & 0x000001) ptr->size += 1 + (ptr->URI ? strlen(ptr->URI) : 0);
183 	return GF_OK;
184 }
185 #endif /*GPAC_DISABLE_ISOM_WRITE*/
186 
187 /* SchemeInformation Box */
schi_box_new()188 GF_Box *schi_box_new()
189 {
190 	ISOM_DECL_BOX_ALLOC(GF_SchemeInformationBox, GF_ISOM_BOX_TYPE_SCHI);
191 	return (GF_Box *)tmp;
192 }
193 
schi_box_del(GF_Box * s)194 void schi_box_del(GF_Box *s)
195 {
196 	gf_free(s);
197 }
198 
schi_on_child_box(GF_Box * s,GF_Box * a)199 GF_Err schi_on_child_box(GF_Box *s, GF_Box *a)
200 {
201 	GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
202 	switch (a->type) {
203 	case GF_ISOM_BOX_TYPE_IKMS:
204 		if (ptr->ikms) ERROR_ON_DUPLICATED_BOX(a, ptr)
205 		ptr->ikms = (GF_ISMAKMSBox*)a;
206 		return GF_OK;
207 	case GF_ISOM_BOX_TYPE_ISFM:
208 		if (ptr->isfm) ERROR_ON_DUPLICATED_BOX(a, ptr)
209 		ptr->isfm = (GF_ISMASampleFormatBox*)a;
210 		return GF_OK;
211 	case GF_ISOM_BOX_TYPE_ISLT:
212 		if (ptr->islt) ERROR_ON_DUPLICATED_BOX(a, ptr)
213 		ptr->islt = (GF_ISMACrypSaltBox*)a;
214 		return GF_OK;
215 	case GF_ISOM_BOX_TYPE_ODKM:
216 		if (ptr->odkm) ERROR_ON_DUPLICATED_BOX(a, ptr)
217 		ptr->odkm = (GF_OMADRMKMSBox*)a;
218 		return GF_OK;
219 	case GF_ISOM_BOX_TYPE_TENC:
220 		if (ptr->tenc) ERROR_ON_DUPLICATED_BOX(a, ptr)
221 		ptr->tenc = (GF_TrackEncryptionBox *)a;
222 		return GF_OK;
223 	case GF_ISOM_BOX_TYPE_ADKM:
224 		if (ptr->adkm) ERROR_ON_DUPLICATED_BOX(a, ptr)
225 		ptr->adkm = (GF_AdobeDRMKeyManagementSystemBox *)a;
226 		return GF_OK;
227 	case GF_ISOM_BOX_TYPE_UUID:
228 		if (((GF_UUIDBox*)a)->internal_4cc==GF_ISOM_BOX_UUID_TENC) {
229 			if (ptr->piff_tenc) return GF_ISOM_INVALID_FILE;
230 			ptr->piff_tenc = (GF_PIFFTrackEncryptionBox *)a;
231 			return GF_OK;
232 		} else {
233 			return GF_OK;
234 		}
235 	}
236 	return GF_OK;
237 }
238 
schi_box_read(GF_Box * s,GF_BitStream * bs)239 GF_Err schi_box_read(GF_Box *s, GF_BitStream *bs)
240 {
241 	return gf_isom_box_array_read(s, bs, schi_on_child_box);
242 }
243 
244 #ifndef GPAC_DISABLE_ISOM_WRITE
schi_box_write(GF_Box * s,GF_BitStream * bs)245 GF_Err schi_box_write(GF_Box *s, GF_BitStream *bs)
246 {
247 	return gf_isom_box_write_header(s, bs);
248 }
249 
schi_box_size(GF_Box * s)250 GF_Err schi_box_size(GF_Box *s)
251 {
252 	u32 pos=0;
253 	GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
254 
255 	gf_isom_check_position(s, (GF_Box *)ptr->ikms, &pos);
256 	gf_isom_check_position(s, (GF_Box *)ptr->isfm, &pos);
257 	gf_isom_check_position(s, (GF_Box *)ptr->islt, &pos);
258 	gf_isom_check_position(s, (GF_Box *)ptr->odkm, &pos);
259 	gf_isom_check_position(s, (GF_Box *)ptr->tenc, &pos);
260 	gf_isom_check_position(s, (GF_Box *)ptr->adkm, &pos);
261 	gf_isom_check_position(s, (GF_Box *)ptr->piff_tenc, &pos);
262 	return GF_OK;
263 }
264 
265 #endif /*GPAC_DISABLE_ISOM_WRITE*/
266 
267 /* ISMAKMS Box */
iKMS_box_new()268 GF_Box *iKMS_box_new()
269 {
270 	ISOM_DECL_BOX_ALLOC(GF_ISMAKMSBox, GF_ISOM_BOX_TYPE_IKMS);
271 	return (GF_Box *)tmp;
272 }
273 
iKMS_box_del(GF_Box * s)274 void iKMS_box_del(GF_Box *s)
275 {
276 	GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
277 	if (ptr == NULL) return;
278 	if (ptr->URI) gf_free(ptr->URI);
279 	gf_free(ptr);
280 }
281 
iKMS_box_read(GF_Box * s,GF_BitStream * bs)282 GF_Err iKMS_box_read(GF_Box *s, GF_BitStream *bs)
283 {
284 	u32 len;
285 	GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
286 
287 	len = (u32) (ptr->size);
288 	ptr->URI = (char*) gf_malloc(sizeof(char)*len);
289 	if (!ptr->URI) return GF_OUT_OF_MEM;
290 	gf_bs_read_data(bs, ptr->URI, len);
291 	return GF_OK;
292 }
293 
294 #ifndef GPAC_DISABLE_ISOM_WRITE
iKMS_box_write(GF_Box * s,GF_BitStream * bs)295 GF_Err iKMS_box_write(GF_Box *s, GF_BitStream *bs)
296 {
297 	GF_Err e;
298 	GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
299 	if (!s) return GF_BAD_PARAM;
300 	e = gf_isom_full_box_write(s, bs);
301 	if (e) return e;
302     if (ptr->URI)
303         gf_bs_write_data(bs, ptr->URI, (u32) strlen(ptr->URI));
304     gf_bs_write_u8(bs, 0);
305 	return GF_OK;
306 }
307 
iKMS_box_size(GF_Box * s)308 GF_Err iKMS_box_size(GF_Box *s)
309 {
310 	GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
311     ptr->size += (ptr->URI ? strlen(ptr->URI) : 0) + 1;
312 	return GF_OK;
313 }
314 #endif /*GPAC_DISABLE_ISOM_WRITE*/
315 
316 /* ISMASampleFormat Box */
iSFM_box_new()317 GF_Box *iSFM_box_new()
318 {
319 	ISOM_DECL_BOX_ALLOC(GF_ISMASampleFormatBox, GF_ISOM_BOX_TYPE_ISFM);
320 	return (GF_Box *)tmp;
321 }
322 
iSFM_box_del(GF_Box * s)323 void iSFM_box_del(GF_Box *s)
324 {
325 	GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
326 	if (ptr == NULL) return;
327 	gf_free(ptr);
328 }
329 
330 
iSFM_box_read(GF_Box * s,GF_BitStream * bs)331 GF_Err iSFM_box_read(GF_Box *s, GF_BitStream *bs)
332 {
333 	GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
334 
335 	ISOM_DECREASE_SIZE(ptr, 3);
336 	ptr->selective_encryption = gf_bs_read_int(bs, 1);
337 	gf_bs_read_int(bs, 7);
338 	ptr->key_indicator_length = gf_bs_read_u8(bs);
339 	ptr->IV_length = gf_bs_read_u8(bs);
340 	return GF_OK;
341 }
342 
343 #ifndef GPAC_DISABLE_ISOM_WRITE
iSFM_box_write(GF_Box * s,GF_BitStream * bs)344 GF_Err iSFM_box_write(GF_Box *s, GF_BitStream *bs)
345 {
346 	GF_Err e;
347 	GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
348 	if (!s) return GF_BAD_PARAM;
349 	e = gf_isom_full_box_write(s, bs);
350 	if (e) return e;
351 	gf_bs_write_int(bs, ptr->selective_encryption, 1);
352 	gf_bs_write_int(bs, 0, 7);
353 	gf_bs_write_u8(bs, ptr->key_indicator_length);
354 	gf_bs_write_u8(bs, ptr->IV_length);
355 	return GF_OK;
356 }
357 
iSFM_box_size(GF_Box * s)358 GF_Err iSFM_box_size(GF_Box *s)
359 {
360 	GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
361 	ptr->size += 3;
362 	return GF_OK;
363 }
364 #endif /*GPAC_DISABLE_ISOM_WRITE*/
365 
366 /* ISMASampleFormat Box */
iSLT_box_new()367 GF_Box *iSLT_box_new()
368 {
369 	ISOM_DECL_BOX_ALLOC(GF_ISMACrypSaltBox, GF_ISOM_BOX_TYPE_ISLT);
370 	return (GF_Box *)tmp;
371 }
372 
iSLT_box_del(GF_Box * s)373 void iSLT_box_del(GF_Box *s)
374 {
375 	GF_ISMACrypSaltBox *ptr = (GF_ISMACrypSaltBox *)s;
376 	if (ptr == NULL) return;
377 	gf_free(ptr);
378 }
379 
380 
iSLT_box_read(GF_Box * s,GF_BitStream * bs)381 GF_Err iSLT_box_read(GF_Box *s, GF_BitStream *bs)
382 {
383 	GF_ISMACrypSaltBox *ptr = (GF_ISMACrypSaltBox *)s;
384 	if (ptr == NULL) return GF_BAD_PARAM;
385 	ISOM_DECREASE_SIZE(ptr, 8);
386 	ptr->salt = gf_bs_read_u64(bs);
387 	return GF_OK;
388 }
389 
390 #ifndef GPAC_DISABLE_ISOM_WRITE
iSLT_box_write(GF_Box * s,GF_BitStream * bs)391 GF_Err iSLT_box_write(GF_Box *s, GF_BitStream *bs)
392 {
393 	GF_Err e;
394 	GF_ISMACrypSaltBox *ptr = (GF_ISMACrypSaltBox *)s;
395 	if (!s) return GF_BAD_PARAM;
396 	e = gf_isom_full_box_write(s, bs);
397 	if (e) return e;
398 
399 	gf_bs_write_u64(bs, ptr->salt);
400 	return GF_OK;
401 }
402 
iSLT_box_size(GF_Box * s)403 GF_Err iSLT_box_size(GF_Box *s)
404 {
405 	s->size += 8;
406 	return GF_OK;
407 }
408 #endif /*GPAC_DISABLE_ISOM_WRITE*/
409 
410 
411 
412 /* OMADRMCommonHeader Box */
ohdr_box_new()413 GF_Box *ohdr_box_new()
414 {
415 	ISOM_DECL_BOX_ALLOC(GF_OMADRMCommonHeaderBox, GF_ISOM_BOX_TYPE_OHDR);
416 	tmp->child_boxes = gf_list_new();
417 	return (GF_Box *)tmp;
418 }
419 
ohdr_box_del(GF_Box * s)420 void ohdr_box_del(GF_Box *s)
421 {
422 	GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;
423 	if (ptr == NULL) return;
424 	if (ptr->ContentID) gf_free(ptr->ContentID);
425 	if (ptr->RightsIssuerURL) gf_free(ptr->RightsIssuerURL);
426 	if (ptr->TextualHeaders) gf_free(ptr->TextualHeaders);
427 	gf_free(ptr);
428 }
429 
ohdr_box_read(GF_Box * s,GF_BitStream * bs)430 GF_Err ohdr_box_read(GF_Box *s, GF_BitStream *bs)
431 {
432 	u16 cid_len, ri_len;
433 	GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;
434 
435 	ISOM_DECREASE_SIZE(ptr, (1+1+8+2+2+2) );
436 	ptr->EncryptionMethod = gf_bs_read_u8(bs);
437 	ptr->PaddingScheme = gf_bs_read_u8(bs);
438 	ptr->PlaintextLength = gf_bs_read_u64(bs);
439 	cid_len = gf_bs_read_u16(bs);
440 	ri_len = gf_bs_read_u16(bs);
441 	ptr->TextualHeadersLen = gf_bs_read_u16(bs);
442 
443 	if (ptr->size<cid_len+ri_len+ptr->TextualHeadersLen) return GF_ISOM_INVALID_FILE;
444 
445 	if (cid_len) {
446 		ptr->ContentID = (char *)gf_malloc(sizeof(char)*(cid_len+1));
447 		if (!ptr->ContentID) return GF_OUT_OF_MEM;
448 		gf_bs_read_data(bs, ptr->ContentID, cid_len);
449 		ptr->ContentID[cid_len]=0;
450 	}
451 
452 	if (ri_len) {
453 		ptr->RightsIssuerURL = (char *)gf_malloc(sizeof(char)*(ri_len+1));
454 		if (!ptr->RightsIssuerURL) return GF_OUT_OF_MEM;
455 		gf_bs_read_data(bs, ptr->RightsIssuerURL, ri_len);
456 		ptr->RightsIssuerURL[ri_len]=0;
457 	}
458 
459 	if (ptr->TextualHeadersLen) {
460 		ptr->TextualHeaders = (char *)gf_malloc(sizeof(char)*(ptr->TextualHeadersLen+1));
461 		if (!ptr->TextualHeaders) return GF_OUT_OF_MEM;
462 		gf_bs_read_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen);
463 		ptr->TextualHeaders[ptr->TextualHeadersLen] = 0;
464 	}
465 
466 	ISOM_DECREASE_SIZE(ptr, (cid_len+ri_len+ptr->TextualHeadersLen) );
467 
468 	return gf_isom_box_array_read(s, bs, NULL);
469 }
470 
471 #ifndef GPAC_DISABLE_ISOM_WRITE
ohdr_box_write(GF_Box * s,GF_BitStream * bs)472 GF_Err ohdr_box_write(GF_Box *s, GF_BitStream *bs)
473 {
474 	u16 cid_len, ri_len;
475 	GF_Err e;
476 	GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s;
477 	if (!s) return GF_BAD_PARAM;
478 	e = gf_isom_full_box_write(s, bs);
479 	if (e) return e;
480 	gf_bs_write_u8(bs, ptr->EncryptionMethod);
481 	gf_bs_write_u8(bs, ptr->PaddingScheme);
482 	gf_bs_write_u64(bs, ptr->PlaintextLength);
483 
484 	cid_len = ptr->ContentID ? (u16) strlen(ptr->ContentID) : 0;
485 	gf_bs_write_u16(bs, cid_len);
486 	ri_len = ptr->RightsIssuerURL ? (u16) strlen(ptr->RightsIssuerURL) : 0;
487 	gf_bs_write_u16(bs, ri_len);
488 	gf_bs_write_u16(bs, ptr->TextualHeadersLen);
489 
490 	if (cid_len) gf_bs_write_data(bs, ptr->ContentID, (u32) strlen(ptr->ContentID));
491 	if (ri_len) gf_bs_write_data(bs, ptr->RightsIssuerURL, (u32) strlen(ptr->RightsIssuerURL));
492 	if (ptr->TextualHeadersLen) gf_bs_write_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen);
493 
494 	ISOM_DECREASE_SIZE(ptr, (cid_len+ri_len+ptr->TextualHeadersLen) );
495 	return GF_OK;
496 }
497 
ohdr_box_size(GF_Box * s)498 GF_Err ohdr_box_size(GF_Box *s)
499 {
500 	GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s;
501 	ptr->size += 1+1+8+2+2+2;
502 	if (ptr->ContentID) ptr->size += strlen(ptr->ContentID);
503 	if (ptr->RightsIssuerURL) ptr->size += strlen(ptr->RightsIssuerURL);
504 	if (ptr->TextualHeadersLen) ptr->size += ptr->TextualHeadersLen;
505 	return GF_OK;
506 }
507 #endif /*GPAC_DISABLE_ISOM_WRITE*/
508 
509 
510 /* OMADRMGroupID Box */
grpi_box_new()511 GF_Box *grpi_box_new()
512 {
513 	ISOM_DECL_BOX_ALLOC(GF_OMADRMGroupIDBox, GF_ISOM_BOX_TYPE_GRPI);
514 	return (GF_Box *)tmp;
515 }
516 
grpi_box_del(GF_Box * s)517 void grpi_box_del(GF_Box *s)
518 {
519 	GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
520 	if (ptr == NULL) return;
521 	if (ptr->GroupID) gf_free(ptr->GroupID);
522 	if (ptr->GroupKey) gf_free(ptr->GroupKey);
523 	gf_free(ptr);
524 }
525 
grpi_box_read(GF_Box * s,GF_BitStream * bs)526 GF_Err grpi_box_read(GF_Box *s, GF_BitStream *bs)
527 {
528 	u16 gid_len;
529 	GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox*)s;
530 
531 	ISOM_DECREASE_SIZE(ptr, (1+2+2) );
532 	gid_len = gf_bs_read_u16(bs);
533 	ptr->GKEncryptionMethod = gf_bs_read_u8(bs);
534 	ptr->GKLength = gf_bs_read_u16(bs);
535 
536 	if (ptr->size<gid_len+ptr->GKLength) return GF_ISOM_INVALID_FILE;
537 
538 	ptr->GroupID = gf_malloc(sizeof(char)*(gid_len+1));
539 	if (!ptr->GroupID) return GF_OUT_OF_MEM;
540 	gf_bs_read_data(bs, ptr->GroupID, gid_len);
541 	ptr->GroupID[gid_len]=0;
542 
543 	ptr->GroupKey = (char *)gf_malloc(sizeof(char)*ptr->GKLength);
544 	if (!ptr->GroupKey) return GF_OUT_OF_MEM;
545 	gf_bs_read_data(bs, ptr->GroupKey, ptr->GKLength);
546 	ISOM_DECREASE_SIZE(ptr, (gid_len+ptr->GKLength) );
547 	return GF_OK;
548 }
549 
550 #ifndef GPAC_DISABLE_ISOM_WRITE
grpi_box_write(GF_Box * s,GF_BitStream * bs)551 GF_Err grpi_box_write(GF_Box *s, GF_BitStream *bs)
552 {
553 	GF_Err e;
554 	u16 gid_len;
555 	GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
556 	if (!s) return GF_BAD_PARAM;
557 	e = gf_isom_full_box_write(s, bs);
558 	if (e) return e;
559 	gid_len = ptr->GroupID ? (u16) strlen(ptr->GroupID) : 0;
560 	gf_bs_write_u16(bs, gid_len);
561 	gf_bs_write_u8(bs, ptr->GKEncryptionMethod);
562 	gf_bs_write_u16(bs, ptr->GKLength);
563 	gf_bs_write_data(bs, ptr->GroupID, gid_len);
564 	gf_bs_write_data(bs, ptr->GroupKey, ptr->GKLength);
565 	return GF_OK;
566 }
567 
grpi_box_size(GF_Box * s)568 GF_Err grpi_box_size(GF_Box *s)
569 {
570 	GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
571 	ptr->size += 2+2+1 + ptr->GKLength;
572 	if (ptr->GroupID) ptr->size += strlen(ptr->GroupID);
573 	return GF_OK;
574 }
575 #endif /*GPAC_DISABLE_ISOM_WRITE*/
576 
577 
578 
579 
580 /* OMADRMMutableInformation Box */
mdri_box_new()581 GF_Box *mdri_box_new()
582 {
583 	ISOM_DECL_BOX_ALLOC(GF_OMADRMMutableInformationBox, GF_ISOM_BOX_TYPE_MDRI);
584 	return (GF_Box *)tmp;
585 }
586 
mdri_box_del(GF_Box * s)587 void mdri_box_del(GF_Box *s)
588 {
589 	GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s;
590 	if (ptr == NULL) return;
591 	gf_free(ptr);
592 }
593 
mdri_box_read(GF_Box * s,GF_BitStream * bs)594 GF_Err mdri_box_read(GF_Box *s, GF_BitStream *bs)
595 {
596 	return gf_isom_box_array_read(s, bs, NULL);
597 }
598 
599 #ifndef GPAC_DISABLE_ISOM_WRITE
mdri_box_write(GF_Box * s,GF_BitStream * bs)600 GF_Err mdri_box_write(GF_Box *s, GF_BitStream *bs)
601 {
602 //	GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s;
603 	GF_Err e = gf_isom_box_write_header(s, bs);
604 	if (e) return e;
605 	return GF_OK;
606 }
607 
mdri_box_size(GF_Box * s)608 GF_Err mdri_box_size(GF_Box *s)
609 {
610 	return GF_OK;
611 }
612 #endif /*GPAC_DISABLE_ISOM_WRITE*/
613 
614 
615 /* OMADRMTransactionTracking Box */
odtt_box_new()616 GF_Box *odtt_box_new()
617 {
618 	ISOM_DECL_BOX_ALLOC(GF_OMADRMTransactionTrackingBox, GF_ISOM_BOX_TYPE_ODTT);
619 	return (GF_Box *)tmp;
620 }
621 
odtt_box_del(GF_Box * s)622 void odtt_box_del(GF_Box *s)
623 {
624 	GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s;
625 	gf_free(ptr);
626 }
627 
odtt_box_read(GF_Box * s,GF_BitStream * bs)628 GF_Err odtt_box_read(GF_Box *s, GF_BitStream *bs)
629 {
630 	GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox *)s;
631 
632 	gf_bs_read_data(bs, ptr->TransactionID, 16);
633 	ISOM_DECREASE_SIZE(ptr, 16);
634 	return GF_OK;
635 }
636 
637 #ifndef GPAC_DISABLE_ISOM_WRITE
odtt_box_write(GF_Box * s,GF_BitStream * bs)638 GF_Err odtt_box_write(GF_Box *s, GF_BitStream *bs)
639 {
640 	GF_Err e;
641 	GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s;
642 	if (!s) return GF_BAD_PARAM;
643 	e = gf_isom_full_box_write(s, bs);
644 	if (e) return e;
645 	gf_bs_write_data(bs, ptr->TransactionID, 16);
646 	return GF_OK;
647 }
648 
odtt_box_size(GF_Box * s)649 GF_Err odtt_box_size(GF_Box *s)
650 {
651 	s->size += 16;
652 	return GF_OK;
653 }
654 #endif /*GPAC_DISABLE_ISOM_WRITE*/
655 
656 
657 
658 /* OMADRMRightsObject Box */
odrb_box_new()659 GF_Box *odrb_box_new()
660 {
661 	ISOM_DECL_BOX_ALLOC(GF_OMADRMRightsObjectBox, GF_ISOM_BOX_TYPE_ODRB);
662 	return (GF_Box *)tmp;
663 }
664 
odrb_box_del(GF_Box * s)665 void odrb_box_del(GF_Box *s)
666 {
667 	GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox*)s;
668 	if (ptr->oma_ro) gf_free(ptr->oma_ro);
669 	gf_free(ptr);
670 }
671 
odrb_box_read(GF_Box * s,GF_BitStream * bs)672 GF_Err odrb_box_read(GF_Box *s, GF_BitStream *bs)
673 {
674 	GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
675 
676 	ptr->oma_ro_size = (u32) ptr->size;
677 	ptr->oma_ro = (char*) gf_malloc(sizeof(char)*ptr->oma_ro_size);
678 	if (!ptr->oma_ro) return GF_OUT_OF_MEM;
679 	gf_bs_read_data(bs, ptr->oma_ro, ptr->oma_ro_size);
680 	ptr->size = 0;
681 	return GF_OK;
682 }
683 
684 #ifndef GPAC_DISABLE_ISOM_WRITE
odrb_box_write(GF_Box * s,GF_BitStream * bs)685 GF_Err odrb_box_write(GF_Box *s, GF_BitStream *bs)
686 {
687 	GF_Err e;
688 	GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
689 	if (!s) return GF_BAD_PARAM;
690 	e = gf_isom_full_box_write(s, bs);
691 	if (e) return e;
692 	gf_bs_write_data(bs, ptr->oma_ro, ptr->oma_ro_size);
693 	return GF_OK;
694 }
695 
odrb_box_size(GF_Box * s)696 GF_Err odrb_box_size(GF_Box *s)
697 {
698 	GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
699 	s->size += ptr->oma_ro_size;
700 	return GF_OK;
701 }
702 #endif /*GPAC_DISABLE_ISOM_WRITE*/
703 
704 
705 
706 
707 /* OMADRMKMS Box */
odkm_box_new()708 GF_Box *odkm_box_new()
709 {
710 	ISOM_DECL_BOX_ALLOC(GF_OMADRMKMSBox, GF_ISOM_BOX_TYPE_ODKM);
711 	return (GF_Box *)tmp;
712 }
713 
odkm_box_del(GF_Box * s)714 void odkm_box_del(GF_Box *s)
715 {
716 	gf_free(s);
717 }
718 
odkm_Add(GF_Box * s,GF_Box * a)719 GF_Err odkm_Add(GF_Box *s, GF_Box *a)
720 {
721 	GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
722 	switch (a->type) {
723 	case GF_ISOM_BOX_TYPE_OHDR:
724 		if (ptr->hdr) ERROR_ON_DUPLICATED_BOX(a, ptr)
725 		ptr->hdr = (GF_OMADRMCommonHeaderBox *)a;
726 		return GF_OK;
727 	case GF_ISOM_BOX_TYPE_ODAF:
728 		if (ptr->fmt) ERROR_ON_DUPLICATED_BOX(a, ptr)
729 		ptr->fmt = (GF_OMADRMAUFormatBox*)a;
730 		return GF_OK;
731 	}
732 	return GF_OK;
733 }
734 
odkm_box_read(GF_Box * s,GF_BitStream * bs)735 GF_Err odkm_box_read(GF_Box *s, GF_BitStream *bs)
736 {
737 	return gf_isom_box_array_read(s, bs, odkm_Add);
738 }
739 
740 #ifndef GPAC_DISABLE_ISOM_WRITE
odkm_box_write(GF_Box * s,GF_BitStream * bs)741 GF_Err odkm_box_write(GF_Box *s, GF_BitStream *bs)
742 {
743 	return gf_isom_full_box_write(s, bs);
744 }
745 
odkm_box_size(GF_Box * s)746 GF_Err odkm_box_size(GF_Box *s)
747 {
748 	u32 pos=0;
749 	GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
750 	gf_isom_check_position(s, (GF_Box *)ptr->hdr, &pos);
751 	gf_isom_check_position(s, (GF_Box *)ptr->fmt, &pos);
752 	return GF_OK;
753 }
754 #endif /*GPAC_DISABLE_ISOM_WRITE*/
755 
756 
757 
758 
pssh_box_new()759 GF_Box *pssh_box_new()
760 {
761 	ISOM_DECL_BOX_ALLOC(GF_ProtectionSystemHeaderBox, GF_ISOM_BOX_TYPE_PSSH);
762 	return (GF_Box *)tmp;
763 }
764 
pssh_box_del(GF_Box * s)765 void pssh_box_del(GF_Box *s)
766 {
767 	GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*)s;
768 	if (ptr == NULL) return;
769 	if (ptr->private_data) gf_free(ptr->private_data);
770 	if (ptr->KIDs) gf_free(ptr->KIDs);
771 	gf_free(ptr);
772 }
773 
pssh_box_read(GF_Box * s,GF_BitStream * bs)774 GF_Err pssh_box_read(GF_Box *s, GF_BitStream *bs)
775 {
776 	GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *)s;
777 
778 	gf_bs_read_data(bs, (char *) ptr->SystemID, 16);
779 	ISOM_DECREASE_SIZE(ptr, 16);
780 	if (ptr->version > 0) {
781 		ptr->KID_count = gf_bs_read_u32(bs);
782 		ISOM_DECREASE_SIZE(ptr, 4);
783 		if (ptr->KID_count) {
784 			u32 i;
785 			if (ptr->size < ptr->KID_count * sizeof(bin128))
786 				return GF_ISOM_INVALID_FILE;
787 			ptr->KIDs = gf_malloc(ptr->KID_count*sizeof(bin128));
788 			if (!ptr->KIDs)
789 				return GF_OUT_OF_MEM;
790 			for (i=0; i<ptr->KID_count; i++) {
791 				gf_bs_read_data(bs, (char *) ptr->KIDs[i], 16);
792 				ISOM_DECREASE_SIZE(ptr, 16);
793 			}
794 		}
795 	}
796 	ptr->private_data_size = gf_bs_read_u32(bs);
797 	ISOM_DECREASE_SIZE(ptr, 4);
798 	if (ptr->private_data_size) {
799 		if (ptr->size < ptr->private_data_size)
800 			return GF_ISOM_INVALID_FILE;
801 		ptr->private_data = gf_malloc(sizeof(char)*ptr->private_data_size);
802 		if (!ptr->private_data)
803 			return GF_OUT_OF_MEM;
804 		gf_bs_read_data(bs, (char *) ptr->private_data, ptr->private_data_size);
805 		ISOM_DECREASE_SIZE(ptr, ptr->private_data_size);
806 	}
807 	return GF_OK;
808 }
809 
810 #ifndef GPAC_DISABLE_ISOM_WRITE
811 
pssh_box_write(GF_Box * s,GF_BitStream * bs)812 GF_Err pssh_box_write(GF_Box *s, GF_BitStream *bs)
813 {
814 	GF_Err e;
815 	GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *) s;
816 	if (!s) return GF_BAD_PARAM;
817 	e = gf_isom_full_box_write(s, bs);
818 	if (e) return e;
819 
820 	gf_bs_write_data(bs, (char *) ptr->SystemID, 16);
821 	if (ptr->version > 0) {
822 		u32 i;
823 		gf_bs_write_u32(bs, ptr->KID_count);
824 		for (i=0; i<ptr->KID_count; i++)
825 			gf_bs_write_data(bs, (char *) ptr->KIDs[i], 16);
826 	}
827 	if (ptr->private_data) {
828 		gf_bs_write_u32(bs, ptr->private_data_size);
829 		gf_bs_write_data(bs, (char *) ptr->private_data, ptr->private_data_size);
830 	} else
831 		gf_bs_write_u32(bs, 0);
832 	return GF_OK;
833 }
834 
pssh_box_size(GF_Box * s)835 GF_Err pssh_box_size(GF_Box *s)
836 {
837 	GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*)s;
838 
839 	if (ptr->KID_count && !ptr->version) {
840 		ptr->version = 1;
841 	}
842 
843 	ptr->size += 16;
844 	if (ptr->version) ptr->size += 4 + 16*ptr->KID_count;
845 	ptr->size += 4 + (ptr->private_data ? ptr->private_data_size : 0);
846 	return GF_OK;
847 }
848 #endif //GPAC_DISABLE_ISOM_WRITE
849 
850 
tenc_box_new()851 GF_Box *tenc_box_new()
852 {
853 	ISOM_DECL_BOX_ALLOC(GF_TrackEncryptionBox, GF_ISOM_BOX_TYPE_TENC);
854 	return (GF_Box *)tmp;
855 }
856 
tenc_box_del(GF_Box * s)857 void tenc_box_del(GF_Box *s)
858 {
859 	gf_free(s);
860 }
861 
tenc_box_read(GF_Box * s,GF_BitStream * bs)862 GF_Err tenc_box_read(GF_Box *s, GF_BitStream *bs)
863 {
864 	GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*)s;
865 
866 	ISOM_DECREASE_SIZE(ptr, 20);
867 
868 	gf_bs_read_u8(bs); //reserved
869 	if (!ptr->version) {
870 		gf_bs_read_u8(bs); //reserved
871 	} else {
872 		ptr->crypt_byte_block = gf_bs_read_int(bs, 4);
873 		ptr->skip_byte_block = gf_bs_read_int(bs, 4);
874 	}
875 	ptr->isProtected = gf_bs_read_u8(bs);
876 	ptr->Per_Sample_IV_Size = gf_bs_read_u8(bs);
877 	gf_bs_read_data(bs, (char *) ptr->KID, 16);
878 
879 
880 	if ((ptr->isProtected == 1) && !ptr->Per_Sample_IV_Size) {
881 		ptr->constant_IV_size = gf_bs_read_u8(bs);
882 		if (ptr->constant_IV_size > sizeof(ptr->constant_IV))
883 			return GF_ISOM_INVALID_FILE;
884 
885 		ISOM_DECREASE_SIZE(ptr, (1 + ptr->constant_IV_size) );
886 		gf_bs_read_data(bs, (char *) ptr->constant_IV, ptr->constant_IV_size);
887 	}
888 	return GF_OK;
889 }
890 
891 #ifndef GPAC_DISABLE_ISOM_WRITE
892 
tenc_box_write(GF_Box * s,GF_BitStream * bs)893 GF_Err tenc_box_write(GF_Box *s, GF_BitStream *bs)
894 {
895 	GF_Err e;
896 	GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox *) s;
897 	if (!s) return GF_BAD_PARAM;
898 	e = gf_isom_full_box_write(s, bs);
899 	if (e) return e;
900 
901 	gf_bs_write_u8(bs, 0x0); //reserved
902 	if (!ptr->version) {
903 		gf_bs_write_u8(bs, 0x0); //reserved
904 	} else {
905 		gf_bs_write_int(bs, ptr->crypt_byte_block, 4);
906 		gf_bs_write_int(bs, ptr->skip_byte_block, 4);
907 	}
908 	gf_bs_write_u8(bs, ptr->isProtected);
909 	gf_bs_write_u8(bs, ptr->Per_Sample_IV_Size);
910 	gf_bs_write_data(bs, (char *) ptr->KID, 16);
911 	if ((ptr->isProtected == 1) && !ptr->Per_Sample_IV_Size) {
912 		gf_bs_write_u8(bs, ptr->constant_IV_size);
913 		gf_bs_write_data(bs,(char *) ptr->constant_IV, ptr->constant_IV_size);
914 	}
915 	return GF_OK;
916 }
917 
tenc_box_size(GF_Box * s)918 GF_Err tenc_box_size(GF_Box *s)
919 {
920 	GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*)s;
921 	ptr->size += 20;
922 	if ((ptr->isProtected == 1) && !ptr->Per_Sample_IV_Size) {
923 		ptr->size += 1 + ptr->constant_IV_size;
924 	}
925 	return GF_OK;
926 }
927 #endif //GPAC_DISABLE_ISOM_WRITE
928 
piff_tenc_box_new()929 GF_Box *piff_tenc_box_new()
930 {
931 	ISOM_DECL_BOX_ALLOC(GF_PIFFTrackEncryptionBox, GF_ISOM_BOX_TYPE_UUID);
932 	tmp->internal_4cc = GF_ISOM_BOX_UUID_TENC;
933 	return (GF_Box *)tmp;
934 }
935 
piff_tenc_box_del(GF_Box * s)936 void piff_tenc_box_del(GF_Box *s)
937 {
938 	gf_free(s);
939 }
940 
piff_tenc_box_read(GF_Box * s,GF_BitStream * bs)941 GF_Err piff_tenc_box_read(GF_Box *s, GF_BitStream *bs)
942 {
943 	GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*)s;
944 
945 	ISOM_DECREASE_SIZE(ptr, 4);
946 	//PIFF TENC extends UUID and fullbox
947 	ptr->version = gf_bs_read_u8(bs);
948 	ptr->flags = gf_bs_read_u24(bs);
949 
950 	ISOM_DECREASE_SIZE(ptr, 20);
951 	ptr->AlgorithmID = gf_bs_read_int(bs, 24);
952 	ptr->IV_size = gf_bs_read_u8(bs);
953 	gf_bs_read_data(bs, (char *) ptr->KID, 16);
954 	return GF_OK;
955 }
956 
957 #ifndef GPAC_DISABLE_ISOM_WRITE
958 
piff_tenc_box_write(GF_Box * s,GF_BitStream * bs)959 GF_Err piff_tenc_box_write(GF_Box *s, GF_BitStream *bs)
960 {
961 	GF_Err e;
962 	GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox *) s;
963 	if (!s) return GF_BAD_PARAM;
964 
965 	e = gf_isom_box_write_header(s, bs);
966 	if (e) return e;
967 	gf_bs_write_u8(bs, ptr->version);
968 	gf_bs_write_u24(bs, ptr->flags);
969 
970 	gf_bs_write_int(bs, ptr->AlgorithmID, 24);
971 	gf_bs_write_u8(bs, ptr->IV_size);
972 	gf_bs_write_data(bs, (char *) ptr->KID, 16);
973 	return GF_OK;
974 }
975 
piff_tenc_box_size(GF_Box * s)976 GF_Err piff_tenc_box_size(GF_Box *s)
977 {
978 	GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*)s;
979 	ptr->size += 24;
980 	return GF_OK;
981 }
982 #endif //GPAC_DISABLE_ISOM_WRITE
983 
984 
piff_psec_box_new()985 GF_Box *piff_psec_box_new()
986 {
987 	ISOM_DECL_BOX_ALLOC(GF_SampleEncryptionBox, GF_ISOM_BOX_TYPE_UUID);
988 	tmp->internal_4cc = GF_ISOM_BOX_UUID_PSEC;
989 	tmp->is_piff = GF_TRUE;
990 	return (GF_Box *)tmp;
991 }
992 
piff_psec_box_del(GF_Box * s)993 void piff_psec_box_del(GF_Box *s)
994 {
995 	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
996 	while (gf_list_count(ptr->samp_aux_info)) {
997 		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, 0);
998 		if (sai) gf_isom_cenc_samp_aux_info_del(sai);
999 		gf_list_rem(ptr->samp_aux_info, 0);
1000 	}
1001 	if (ptr->samp_aux_info) gf_list_del(ptr->samp_aux_info);
1002 	gf_free(s);
1003 }
1004 
1005 
piff_psec_box_read(GF_Box * s,GF_BitStream * bs)1006 GF_Err piff_psec_box_read(GF_Box *s, GF_BitStream *bs)
1007 {
1008 	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
1009 
1010 	ISOM_DECREASE_SIZE(ptr, 4);
1011 	//PIFF PSEC extends UUID and fullbox
1012 	ptr->version = gf_bs_read_u8(bs);
1013 	ptr->flags = gf_bs_read_u24(bs);
1014 
1015 	if (ptr->flags & 1) {
1016 		ISOM_DECREASE_SIZE(ptr, 20);
1017 		ptr->AlgorithmID = gf_bs_read_int(bs, 24);
1018 		ptr->IV_size = gf_bs_read_u8(bs);
1019 		gf_bs_read_data(bs, (char *) ptr->KID, 16);
1020 	}
1021 	if (ptr->IV_size == 0)
1022 		ptr->IV_size = 8; //default to 8
1023 
1024 	ptr->bs_offset = gf_bs_get_position(bs);
1025 
1026 	/*u32 sample_count = */gf_bs_read_u32(bs);
1027 	ISOM_DECREASE_SIZE(ptr, 4);
1028 	if (ptr->IV_size != 8 && ptr->IV_size != 16) {
1029 		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));
1030 		return GF_BAD_PARAM;
1031 	}
1032 	//as for senc, we skip parsing of the box until we have all saiz/saio info
1033 	gf_bs_skip_bytes(bs, ptr->size);
1034 	ptr->size = 0;
1035 	return GF_OK;
1036 }
1037 
1038 #ifndef GPAC_DISABLE_ISOM_WRITE
1039 
store_senc_info(GF_SampleEncryptionBox * ptr,GF_BitStream * bs)1040 GF_Err store_senc_info(GF_SampleEncryptionBox *ptr, GF_BitStream *bs)
1041 {
1042 	GF_Err e;
1043 	u64 pos, new_pos;
1044 	if (!ptr->cenc_saio) return GF_OK;
1045 
1046 	pos = gf_bs_get_position(bs);
1047 	if (pos>0xFFFFFFFFULL) {
1048 		if (ptr->cenc_saio && !ptr->cenc_saio->version) {
1049 			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] saio offset larger than 32-bits but box version 0 enforced. Retry without \"saio32\" option\n"));
1050 			return GF_BAD_PARAM;
1051 		}
1052 	}
1053 	e = gf_bs_seek(bs, ptr->cenc_saio->offset_first_offset_field);
1054 	if (e) return e;
1055 	//force using version 1 for saio box i.e offset has 64 bits
1056 #ifndef GPAC_DISABLE_ISOM_FRAGMENTS
1057 	if (ptr->traf) {
1058 		new_pos = pos - ptr->traf->moof_start_in_bs;
1059 	} else
1060 #endif
1061 	{
1062 		new_pos = pos;
1063 	}
1064 
1065 	if (ptr->cenc_saio->offsets) {
1066 		u32 i;
1067 		u64 old_offset = ptr->cenc_saio->offsets[0];
1068 		for (i=0; i<ptr->cenc_saio->entry_count; i++) {
1069 			if (ptr->cenc_saio->version) {
1070 				gf_bs_write_u64(bs, new_pos + ptr->cenc_saio->offsets[i] - old_offset);
1071 			} else {
1072 				gf_bs_write_u32(bs, (u32) (new_pos + ptr->cenc_saio->offsets[i] - old_offset));
1073 			}
1074 			ptr->cenc_saio->offsets[i] = new_pos + ptr->cenc_saio->offsets[i] - old_offset;
1075 		}
1076 	} else {
1077 		if (ptr->cenc_saio->version) {
1078 			gf_bs_write_u64(bs, new_pos);
1079 		} else {
1080 			gf_bs_write_u32(bs, (u32) new_pos);
1081 		}
1082 	}
1083 
1084 	return gf_bs_seek(bs, pos);
1085 }
1086 
piff_psec_box_write(GF_Box * s,GF_BitStream * bs)1087 GF_Err piff_psec_box_write(GF_Box *s, GF_BitStream *bs)
1088 {
1089 	GF_Err e;
1090 	u32 sample_count;
1091 	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *) s;
1092 	if (!s) return GF_BAD_PARAM;
1093 
1094 	sample_count = gf_list_count(ptr->samp_aux_info);
1095 	if (!sample_count) {
1096 		ptr->size = 0;
1097 		return GF_OK;
1098 	}
1099 	e = gf_isom_box_write_header(s, bs);
1100 	if (e) return e;
1101 	gf_bs_write_u8(bs, ptr->version);
1102 	gf_bs_write_u24(bs, ptr->flags);
1103 
1104 	if (ptr->flags & 1) {
1105 		gf_bs_write_int(bs, ptr->AlgorithmID, 24);
1106 		gf_bs_write_u8(bs, ptr->IV_size);
1107 		gf_bs_write_data(bs, (char *) ptr->KID, 16);
1108 	}
1109 	sample_count = gf_list_count(ptr->samp_aux_info);
1110 	gf_bs_write_u32(bs, sample_count);
1111 	if (sample_count) {
1112 		u32 i, j;
1113 		e = store_senc_info((GF_SampleEncryptionBox *)ptr, bs);
1114 		if (e) return e;
1115 
1116 		for (i = 0; i < sample_count; i++) {
1117 			GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1118 			if (! sai->IV_size) continue;
1119 			gf_bs_write_data(bs, (char *)sai->IV, sai->IV_size);
1120 			gf_bs_write_u16(bs, sai->subsample_count);
1121 			for (j = 0; j < sai->subsample_count; j++) {
1122 				gf_bs_write_u16(bs, sai->subsamples[j].bytes_clear_data);
1123 				gf_bs_write_u32(bs, sai->subsamples[j].bytes_encrypted_data);
1124 			}
1125 		}
1126 	}
1127 	return GF_OK;
1128 }
1129 
piff_psec_box_size(GF_Box * s)1130 GF_Err piff_psec_box_size(GF_Box *s)
1131 {
1132 	u32 i, sample_count;
1133 	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox*)s;
1134 
1135 	sample_count = gf_list_count(ptr->samp_aux_info);
1136 	if (!sample_count) {
1137 		ptr->size = 0;
1138 		return GF_OK;
1139 	}
1140 
1141 	ptr->size += 4;
1142 	if (ptr->flags & 1) {
1143 		ptr->size += 20;
1144 	}
1145 	ptr->size += 4;
1146 
1147 	for (i = 0; i < sample_count; i++) {
1148 		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1149 		if (! sai->IV_size) continue;
1150 		ptr->size += 2 + sai->IV_size + 6*sai->subsample_count;
1151 	}
1152 	return GF_OK;
1153 }
1154 #endif //GPAC_DISABLE_ISOM_WRITE
1155 
1156 
piff_pssh_box_new()1157 GF_Box *piff_pssh_box_new()
1158 {
1159 	ISOM_DECL_BOX_ALLOC(GF_PIFFProtectionSystemHeaderBox, GF_ISOM_BOX_TYPE_UUID);
1160 	tmp->internal_4cc = GF_ISOM_BOX_UUID_PSSH;
1161 	return (GF_Box *)tmp;
1162 }
1163 
piff_pssh_box_del(GF_Box * s)1164 void piff_pssh_box_del(GF_Box *s)
1165 {
1166 	gf_free(s);
1167 }
1168 
piff_pssh_box_read(GF_Box * s,GF_BitStream * bs)1169 GF_Err piff_pssh_box_read(GF_Box *s, GF_BitStream *bs)
1170 {
1171 	GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s;
1172 
1173 	ISOM_DECREASE_SIZE(ptr, 24);
1174 	//PIFF PSSH extends UUID and fullbox
1175 	ptr->version = gf_bs_read_u8(bs);
1176 	ptr->flags = gf_bs_read_u24(bs);
1177 	gf_bs_read_data(bs, (char *) ptr->SystemID, 16);
1178 	ptr->private_data_size = gf_bs_read_u32(bs);
1179 
1180 	if (ptr->size < sizeof(char)*ptr->private_data_size)
1181 	    return GF_ISOM_INVALID_FILE;
1182 	ptr->private_data = gf_malloc(sizeof(char)*ptr->private_data_size);
1183 	if (!ptr->private_data)
1184 	    return GF_OUT_OF_MEM;
1185 
1186 	ISOM_DECREASE_SIZE(ptr, ptr->private_data_size);
1187 	gf_bs_read_data(bs, (char *) ptr->private_data, ptr->private_data_size);
1188 	return GF_OK;
1189 }
1190 
1191 #ifndef GPAC_DISABLE_ISOM_WRITE
1192 
piff_pssh_box_write(GF_Box * s,GF_BitStream * bs)1193 GF_Err piff_pssh_box_write(GF_Box *s, GF_BitStream *bs)
1194 {
1195 	GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox *) s;
1196 	GF_Err e = gf_isom_box_write_header(s, bs);
1197 	if (e) return e;
1198 	gf_bs_write_u8(bs, ptr->version);
1199 	gf_bs_write_u24(bs, ptr->flags);
1200 
1201 	gf_bs_write_data(bs, (char *) ptr->SystemID, 16);
1202 	gf_bs_write_u32(bs, ptr->private_data_size);
1203 	gf_bs_write_data(bs, (char *) ptr->private_data, ptr->private_data_size);
1204 	return GF_OK;
1205 }
1206 
piff_pssh_box_size(GF_Box * s)1207 GF_Err piff_pssh_box_size(GF_Box *s)
1208 {
1209 	GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s;
1210 
1211 	ptr->size += 24 + ptr->private_data_size;
1212 	return GF_OK;
1213 }
1214 #endif //GPAC_DISABLE_ISOM_WRITE
1215 
senc_box_new()1216 GF_Box *senc_box_new()
1217 {
1218 	ISOM_DECL_BOX_ALLOC(GF_SampleEncryptionBox, GF_ISOM_BOX_TYPE_SENC);
1219 	return (GF_Box *)tmp;
1220 }
1221 
senc_box_del(GF_Box * s)1222 void senc_box_del(GF_Box *s)
1223 {
1224 	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
1225 	while (gf_list_count(ptr->samp_aux_info)) {
1226 		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, 0);
1227 		if (sai) gf_isom_cenc_samp_aux_info_del(sai);
1228 		gf_list_rem(ptr->samp_aux_info, 0);
1229 	}
1230 	if (ptr->samp_aux_info) gf_list_del(ptr->samp_aux_info);
1231 	gf_free(s);
1232 }
1233 
1234 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
senc_Parse(GF_BitStream * bs,GF_TrackBox * trak,GF_TrackFragmentBox * traf,GF_SampleEncryptionBox * senc)1235 GF_Err senc_Parse(GF_BitStream *bs, GF_TrackBox *trak, GF_TrackFragmentBox *traf, GF_SampleEncryptionBox *senc)
1236 #else
1237 GF_Err senc_Parse(GF_BitStream *bs, GF_TrackBox *trak, void *traf, GF_SampleEncryptionBox *senc)
1238 #endif
1239 {
1240 	GF_Err e;
1241 	Bool parse_failed = GF_FALSE;
1242 	u32 i, j, count, sample_number;
1243 	u32 senc_size = (u32) senc->size;
1244 	u32 subs_size = 0, def_IV_size;
1245 	u64 pos = gf_bs_get_position(bs);
1246 	Bool do_warn = GF_TRUE;
1247 
1248 #ifdef	GPAC_DISABLE_ISOM_FRAGMENTS
1249 	if (!traf)
1250 		return GF_BAD_PARAM;
1251 #endif
1252 
1253 	gf_bs_seek(bs, senc->bs_offset);
1254 
1255 	//BOX + version/flags
1256 	if (senc_size<12) return GF_BAD_PARAM;
1257 	senc_size -= 12;
1258 
1259 	if (senc->is_piff) {
1260 		//UUID
1261 		if (senc_size<16) return GF_BAD_PARAM;
1262 		senc_size -= 16;
1263 	}
1264 	if (senc->flags & 2) subs_size = 8;
1265 
1266 	if (senc_size<4) return GF_BAD_PARAM;
1267 
1268 	sample_number = 1;
1269 #ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
1270 	if (trak) sample_number += trak->sample_count_at_seg_start;
1271 #endif
1272 
1273 	count = gf_bs_read_u32(bs);
1274 	senc_size -= 4;
1275 
1276 	def_IV_size = 0;
1277 	//check the target size if we have one subsample
1278 	if (senc_size >= count * (16 + subs_size)) {
1279 		def_IV_size = 16;
1280 	}
1281 	else if (senc_size >= count * (8 + subs_size)) {
1282 		def_IV_size = 8;
1283 	}
1284 	else if (senc_size >= count * (subs_size)) {
1285 		def_IV_size = 0;
1286 	}
1287 
1288 	if (!senc->samp_aux_info) senc->samp_aux_info = gf_list_new();
1289 	for (i=0; i<count; i++) {
1290 		Bool is_encrypted;
1291 		GF_CENCSampleAuxInfo *sai;
1292 		GF_SAFEALLOC(sai, GF_CENCSampleAuxInfo);
1293 		if (!sai) return GF_OUT_OF_MEM;
1294 
1295 		if (trak) {
1296 			e = gf_isom_get_sample_cenc_info_ex(trak, traf, senc, sample_number, &is_encrypted, &sai->IV_size, NULL, NULL, NULL, NULL, NULL);
1297 			if (e) {
1298 				GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isobmf] could not get cenc info for sample %d: %s\n", sample_number, gf_error_to_string(e) ));
1299 				gf_isom_cenc_samp_aux_info_del(sai);
1300 				return e;
1301 			}
1302 		}
1303 		//no init movie setup (segment dump/inspaction, assume default encrypted and 16 bytes IV
1304 		else {
1305 			if (do_warn) {
1306 				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isobmf] no moov found, cannot get cenc default info, assuming isEncrypted, IV size %d (computed from senc size)\n", def_IV_size));
1307 				do_warn = GF_FALSE;
1308 			}
1309 			is_encrypted = GF_TRUE;
1310 			sai->IV_size = def_IV_size;
1311 		}
1312 		if (senc_size < sai->IV_size) {
1313 			parse_failed = GF_TRUE;
1314 			gf_isom_cenc_samp_aux_info_del(sai);
1315 			break;
1316 		}
1317 
1318 		sample_number++;
1319 
1320 		//subsample info is only signaled for encrypted samples
1321 		if (is_encrypted) {
1322 			if (sai->IV_size > GF_ARRAY_LENGTH(sai->IV)) {
1323 				gf_isom_cenc_samp_aux_info_del(sai);
1324 				GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isobmf] Failed to parse SENC box, invalid SAI size\n" ));
1325 				return GF_ISOM_INVALID_FILE;
1326 			}
1327 			if (sai->IV_size) {
1328 				gf_bs_read_data(bs, (char *)sai->IV, sai->IV_size);
1329 				senc_size -= sai->IV_size;
1330 			}
1331 
1332 			if (senc->flags & 0x00000002) {
1333 				sai->subsample_count = gf_bs_read_u16(bs);
1334 				sai->subsamples = (GF_CENCSubSampleEntry *)gf_malloc(sai->subsample_count*sizeof(GF_CENCSubSampleEntry));
1335 				if (!sai->subsamples) return GF_OUT_OF_MEM;
1336 
1337 				if ((s32) senc_size < 2 + sai->subsample_count * 6) {
1338 					parse_failed = GF_TRUE;
1339 					gf_isom_cenc_samp_aux_info_del(sai);
1340 					break;
1341 				}
1342 
1343 				for (j = 0; j < sai->subsample_count; j++) {
1344 					if (gf_bs_get_size(bs) - gf_bs_get_position(bs) < 6) {
1345 						gf_isom_cenc_samp_aux_info_del(sai);
1346 						if (trak && trak->moov && trak->moov->mov && trak->moov->mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) {
1347 							gf_bs_seek(bs, pos);
1348 							GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isobmf] Failed to parse SENC box, invalid SAI size\n" ));
1349 							return GF_OK;
1350 						}
1351 						return GF_ISOM_INVALID_FILE;
1352 					}
1353 					sai->subsamples[j].bytes_clear_data = gf_bs_read_u16(bs);
1354 					sai->subsamples[j].bytes_encrypted_data = gf_bs_read_u32(bs);
1355 				}
1356 				senc_size -= 2 + sai->subsample_count * 6;
1357 			}
1358 		} else {
1359 			i--;
1360 		}
1361 		gf_list_add(senc->samp_aux_info, sai);
1362 	}
1363 	gf_bs_seek(bs, pos);
1364 	if (parse_failed) {
1365 		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isobmf] cannot parse senc, missing IV/crypto state\n"));
1366 	}
1367 	return GF_OK;
1368 }
1369 
1370 
senc_box_read(GF_Box * s,GF_BitStream * bs)1371 GF_Err senc_box_read(GF_Box *s, GF_BitStream *bs)
1372 {
1373 	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
1374 	ISOM_DECREASE_SIZE(ptr, 4);
1375 	//WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
1376 	ptr->version = gf_bs_read_u8(bs);
1377 	ptr->flags = gf_bs_read_u24(bs);
1378 
1379 	ptr->bs_offset = gf_bs_get_position(bs);
1380 	gf_bs_skip_bytes(bs, ptr->size);
1381 	ptr->size = 0;
1382 	ptr->load_needed = GF_TRUE;
1383 	return GF_OK;
1384 }
1385 
1386 #ifndef GPAC_DISABLE_ISOM_WRITE
1387 
1388 
senc_box_write(GF_Box * s,GF_BitStream * bs)1389 GF_Err senc_box_write(GF_Box *s, GF_BitStream *bs)
1390 {
1391 	GF_Err e;
1392 	u32 i, j;
1393 	u32 sample_count;
1394 	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *) s;
1395 
1396 	sample_count = gf_list_count(ptr->samp_aux_info);
1397 	if (!sample_count) {
1398 		ptr->size = 0;
1399 		return GF_OK;
1400 	}
1401 
1402 	e = gf_isom_box_write_header(s, bs);
1403 	if (e) return e;
1404 	//WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
1405 	gf_bs_write_u8(bs, ptr->version);
1406 	gf_bs_write_u24(bs, ptr->flags);
1407 
1408 	gf_bs_write_u32(bs, sample_count);
1409 
1410 	e = store_senc_info(ptr, bs);
1411 	if (e) return e;
1412 
1413 	for (i = 0; i < sample_count; i++) {
1414 		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1415 
1416 		//for cbcs scheme, IV_size is 0, constant IV shall be used. It is written in tenc box rather than in sai
1417 		if (sai->IV_size)
1418 			gf_bs_write_data(bs, (char *)sai->IV, sai->IV_size);
1419 
1420 		if (ptr->flags & 0x00000002) {
1421 			gf_bs_write_u16(bs, sai->subsample_count);
1422 			for (j = 0; j < sai->subsample_count; j++) {
1423 				gf_bs_write_u16(bs, sai->subsamples[j].bytes_clear_data);
1424 				gf_bs_write_u32(bs, sai->subsamples[j].bytes_encrypted_data);
1425 			}
1426 		}
1427 	}
1428 	return GF_OK;
1429 }
1430 
senc_box_size(GF_Box * s)1431 GF_Err senc_box_size(GF_Box *s)
1432 {
1433 	u32 sample_count;
1434 	u32 i;
1435 	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox*)s;
1436 	sample_count = gf_list_count(ptr->samp_aux_info);
1437 
1438 	if (!sample_count) {
1439 		ptr->size = 0;
1440 		return GF_OK;
1441 	}
1442 
1443 	//WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
1444 	ptr->size += 4; //version and flags
1445 
1446 	ptr->size += 4; //sample count
1447 	for (i = 0; i < sample_count; i++) {
1448 		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
1449 
1450 		ptr->size += sai->IV_size;
1451 
1452 		if (ptr->flags & 0x00000002)
1453 			ptr->size += 2 + 6*sai->subsample_count;
1454 	}
1455 	return GF_OK;
1456 }
1457 #endif //GPAC_DISABLE_ISOM_WRITE
1458 
adkm_box_new()1459 GF_Box *adkm_box_new()
1460 {
1461 	ISOM_DECL_BOX_ALLOC(GF_AdobeDRMKeyManagementSystemBox, GF_ISOM_BOX_TYPE_ADKM);
1462 	tmp->version = 1;
1463 	tmp->flags = 0;
1464 	return (GF_Box *)tmp;
1465 }
1466 
adkm_box_del(GF_Box * s)1467 void adkm_box_del(GF_Box *s)
1468 {
1469 	GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
1470 	if (!ptr) return;
1471 	gf_free(s);
1472 }
1473 
adkm_on_child_box(GF_Box * s,GF_Box * a)1474 GF_Err adkm_on_child_box(GF_Box *s, GF_Box *a)
1475 {
1476 	GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
1477 	switch (a->type) {
1478 	case GF_ISOM_BOX_TYPE_AHDR:
1479 		if (ptr->header) ERROR_ON_DUPLICATED_BOX(a, ptr)
1480 		ptr->header = (GF_AdobeDRMHeaderBox *)a;
1481 		break;
1482 	case GF_ISOM_BOX_TYPE_ADAF:
1483 		if (ptr->au_format) ERROR_ON_DUPLICATED_BOX(a, ptr)
1484 		ptr->au_format = (GF_AdobeDRMAUFormatBox *)a;
1485 		break;
1486 	}
1487 	return GF_OK;
1488 }
1489 
adkm_box_read(GF_Box * s,GF_BitStream * bs)1490 GF_Err adkm_box_read(GF_Box *s, GF_BitStream *bs)
1491 {
1492 	return gf_isom_box_array_read(s, bs, adkm_on_child_box);
1493 }
1494 
1495 #ifndef GPAC_DISABLE_ISOM_WRITE
adkm_box_write(GF_Box * s,GF_BitStream * bs)1496 GF_Err adkm_box_write(GF_Box *s, GF_BitStream *bs)
1497 {
1498 	return gf_isom_full_box_write(s, bs);
1499 }
1500 
adkm_box_size(GF_Box * s)1501 GF_Err adkm_box_size(GF_Box *s)
1502 {
1503 	u32 pos=0;
1504 	GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
1505 	gf_isom_check_position(s, (GF_Box *)ptr->header, &pos);
1506 	gf_isom_check_position(s, (GF_Box *)ptr->au_format, &pos);
1507     return GF_OK;
1508 }
1509 #endif //GPAC_DISABLE_ISOM_WRITE
1510 
ahdr_box_new()1511 GF_Box *ahdr_box_new()
1512 {
1513 	ISOM_DECL_BOX_ALLOC(GF_AdobeDRMHeaderBox, GF_ISOM_BOX_TYPE_AHDR);
1514 	tmp->version = 2;
1515 	tmp->flags = 0;
1516 	return (GF_Box *)tmp;
1517 }
1518 
ahdr_box_del(GF_Box * s)1519 void ahdr_box_del(GF_Box *s)
1520 {
1521 	gf_free(s);
1522 }
1523 
1524 
ahdr_on_child_box(GF_Box * s,GF_Box * a)1525 GF_Err ahdr_on_child_box(GF_Box *s, GF_Box *a)
1526 {
1527 	GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s;
1528 	switch (a->type) {
1529 	case GF_ISOM_BOX_TYPE_APRM:
1530 		if (ptr->std_enc_params) ERROR_ON_DUPLICATED_BOX(a, ptr)
1531 		ptr->std_enc_params = (GF_AdobeStdEncryptionParamsBox *)a;
1532 		break;
1533 	}
1534 	return GF_OK;
1535 }
1536 
ahdr_box_read(GF_Box * s,GF_BitStream * bs)1537 GF_Err ahdr_box_read(GF_Box *s, GF_BitStream *bs)
1538 {
1539 	return gf_isom_box_array_read(s, bs, ahdr_on_child_box);
1540 }
1541 
1542 #ifndef GPAC_DISABLE_ISOM_WRITE
ahdr_box_write(GF_Box * s,GF_BitStream * bs)1543 GF_Err ahdr_box_write(GF_Box *s, GF_BitStream *bs)
1544 {
1545 	return gf_isom_full_box_write(s, bs);
1546 }
1547 
ahdr_box_size(GF_Box * s)1548 GF_Err ahdr_box_size(GF_Box *s)
1549 {
1550 	u32 pos=0;
1551 	GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s;
1552 	gf_isom_check_position(s, (GF_Box *)ptr->std_enc_params, &pos);
1553     return GF_OK;
1554 }
1555 #endif //GPAC_DISABLE_ISOM_WRITE
1556 
aprm_box_new()1557 GF_Box *aprm_box_new()
1558 {
1559 	ISOM_DECL_BOX_ALLOC(GF_AdobeStdEncryptionParamsBox, GF_ISOM_BOX_TYPE_APRM);
1560 	tmp->version = 1;
1561 	tmp->flags = 0;
1562 	return (GF_Box *)tmp;
1563 }
1564 
aprm_box_del(GF_Box * s)1565 void aprm_box_del(GF_Box *s)
1566 {
1567 	gf_free(s);
1568 }
1569 
aprm_on_child_box(GF_Box * s,GF_Box * a)1570 GF_Err aprm_on_child_box(GF_Box *s, GF_Box *a)
1571 {
1572 	GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s;
1573 	switch (a->type) {
1574 	case GF_ISOM_BOX_TYPE_AEIB:
1575 		if (ptr->enc_info) ERROR_ON_DUPLICATED_BOX(a, ptr)
1576 		ptr->enc_info = (GF_AdobeEncryptionInfoBox *)a;
1577 		break;
1578 	case GF_ISOM_BOX_TYPE_AKEY:
1579 		if (ptr->key_info) ERROR_ON_DUPLICATED_BOX(a, ptr)
1580 		ptr->key_info = (GF_AdobeKeyInfoBox *)a;
1581 		break;
1582 	}
1583 	return GF_OK;
1584 }
1585 
aprm_box_read(GF_Box * s,GF_BitStream * bs)1586 GF_Err aprm_box_read(GF_Box *s, GF_BitStream *bs)
1587 {
1588 	return gf_isom_box_array_read(s, bs, aprm_on_child_box);
1589 }
1590 
1591 #ifndef GPAC_DISABLE_ISOM_WRITE
aprm_box_write(GF_Box * s,GF_BitStream * bs)1592 GF_Err aprm_box_write(GF_Box *s, GF_BitStream *bs)
1593 {
1594 	return gf_isom_full_box_write(s, bs);
1595 }
1596 
aprm_box_size(GF_Box * s)1597 GF_Err aprm_box_size(GF_Box *s)
1598 {
1599 	u32 pos=0;
1600 	GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s;
1601 	gf_isom_check_position(s, (GF_Box *)ptr->enc_info, &pos);
1602 	gf_isom_check_position(s, (GF_Box *)ptr->key_info, &pos);
1603     return GF_OK;
1604 }
1605 #endif //GPAC_DISABLE_ISOM_WRITE
1606 
aeib_box_new()1607 GF_Box *aeib_box_new()
1608 {
1609 	ISOM_DECL_BOX_ALLOC(GF_AdobeEncryptionInfoBox, GF_ISOM_BOX_TYPE_AEIB);
1610 	tmp->version = 1;
1611 	tmp->flags = 0;
1612 	return (GF_Box *)tmp;
1613 }
1614 
aeib_box_del(GF_Box * s)1615 void aeib_box_del(GF_Box *s)
1616 {
1617 	GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s;
1618 	if (!ptr) return;
1619 	if (ptr->enc_algo) gf_free(ptr->enc_algo);
1620 	gf_free(ptr);
1621 }
1622 
aeib_box_read(GF_Box * s,GF_BitStream * bs)1623 GF_Err aeib_box_read(GF_Box *s, GF_BitStream *bs)
1624 {
1625 	GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s;
1626 	u32 len;
1627 
1628 	len = (u32) ptr->size - 1;
1629 	if (len) {
1630 		ptr->enc_algo = (char *)gf_malloc(len*sizeof(char));
1631 		if (!ptr->enc_algo) return GF_OUT_OF_MEM;
1632 		gf_bs_read_data(bs, ptr->enc_algo, len);
1633 	}
1634 	ptr->key_length = gf_bs_read_u8(bs);
1635 	ptr->size = 0;
1636 	return GF_OK;
1637 }
1638 
1639 #ifndef GPAC_DISABLE_ISOM_WRITE
1640 
aeib_box_write(GF_Box * s,GF_BitStream * bs)1641 GF_Err aeib_box_write(GF_Box *s, GF_BitStream *bs)
1642 {
1643 	GF_Err e;
1644 	GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox *) s;
1645 	if (!s) return GF_BAD_PARAM;
1646 	e = gf_isom_full_box_write(s, bs);
1647 	if (e) return e;
1648 	if (ptr->enc_algo) {
1649 		gf_bs_write_data(bs, (char *) ptr->enc_algo, (u32) strlen(ptr->enc_algo));
1650 		gf_bs_write_u8(bs, 0); //string end
1651 	}
1652 	gf_bs_write_u8(bs, ptr->key_length);
1653 	return GF_OK;
1654 }
1655 
aeib_box_size(GF_Box * s)1656 GF_Err aeib_box_size(GF_Box *s)
1657 {
1658 	GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s;
1659 	if (ptr->enc_algo)
1660 		ptr->size += strlen(ptr->enc_algo) + 1;
1661 	ptr->size += 1; //KeyLength
1662 	return GF_OK;
1663 }
1664 #endif //GPAC_DISABLE_ISOM_WRITE
1665 
akey_box_new()1666 GF_Box *akey_box_new()
1667 {
1668 	ISOM_DECL_BOX_ALLOC(GF_AdobeKeyInfoBox, GF_ISOM_BOX_TYPE_AKEY);
1669 	tmp->version = 1;
1670 	tmp->flags = 0;
1671 	return (GF_Box *)tmp;
1672 }
1673 
akey_box_del(GF_Box * s)1674 void akey_box_del(GF_Box *s)
1675 {
1676 	gf_free(s);
1677 }
1678 
akey_on_child_box(GF_Box * s,GF_Box * a)1679 GF_Err akey_on_child_box(GF_Box *s, GF_Box *a)
1680 {
1681 	GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s;
1682 	switch (a->type) {
1683 	case GF_ISOM_BOX_TYPE_FLXS:
1684 		if (ptr->params) ERROR_ON_DUPLICATED_BOX(a, ptr)
1685 		ptr->params = (GF_AdobeFlashAccessParamsBox *)a;
1686 		break;
1687 	}
1688 	return GF_OK;
1689 }
1690 
akey_box_read(GF_Box * s,GF_BitStream * bs)1691 GF_Err akey_box_read(GF_Box *s, GF_BitStream *bs)
1692 {
1693 	return gf_isom_box_array_read(s, bs, akey_on_child_box);
1694 }
1695 
1696 #ifndef GPAC_DISABLE_ISOM_WRITE
akey_box_write(GF_Box * s,GF_BitStream * bs)1697 GF_Err akey_box_write(GF_Box *s, GF_BitStream *bs)
1698 {
1699 	return gf_isom_full_box_write(s, bs);
1700 }
1701 
akey_box_size(GF_Box * s)1702 GF_Err akey_box_size(GF_Box *s)
1703 {
1704 	u32 pos=0;
1705 	GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s;
1706 	gf_isom_check_position(s, (GF_Box *)ptr->params, &pos);
1707     return GF_OK;
1708 }
1709 #endif //GPAC_DISABLE_ISOM_WRITE
1710 
flxs_box_new()1711 GF_Box *flxs_box_new()
1712 {
1713 	ISOM_DECL_BOX_ALLOC(GF_AdobeFlashAccessParamsBox, GF_ISOM_BOX_TYPE_FLXS);
1714 	return (GF_Box *)tmp;
1715 }
1716 
flxs_box_del(GF_Box * s)1717 void flxs_box_del(GF_Box *s)
1718 {
1719 	GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s;
1720 	if (!ptr) return;
1721 	if (ptr->metadata)
1722 		gf_free(ptr->metadata);
1723 	gf_free(ptr);
1724 }
1725 
flxs_box_read(GF_Box * s,GF_BitStream * bs)1726 GF_Err flxs_box_read(GF_Box *s, GF_BitStream *bs)
1727 {
1728 	GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s;
1729 	u32 len;
1730 
1731 	len = (u32) ptr->size;
1732 	if (len) {
1733 		ptr->metadata = (char *)gf_malloc(len*sizeof(char));
1734 		if (!ptr->metadata) return GF_OUT_OF_MEM;
1735 		gf_bs_read_data(bs, ptr->metadata, len);
1736 	}
1737 	return GF_OK;
1738 }
1739 
1740 #ifndef GPAC_DISABLE_ISOM_WRITE
1741 
flxs_box_write(GF_Box * s,GF_BitStream * bs)1742 GF_Err flxs_box_write(GF_Box *s, GF_BitStream *bs)
1743 {
1744 	GF_Err e;
1745 	GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox *) s;
1746 	if (!s) return GF_BAD_PARAM;
1747 	e = gf_isom_box_write_header(s, bs);
1748 	if (e) return e;
1749 	if (ptr->metadata) {
1750 		gf_bs_write_data(bs, ptr->metadata, (u32) strlen(ptr->metadata));
1751 		gf_bs_write_u8(bs, 0); //string end
1752 	}
1753 	return GF_OK;
1754 }
1755 
flxs_box_size(GF_Box * s)1756 GF_Err flxs_box_size(GF_Box *s)
1757 {
1758 	GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s;
1759 	if (ptr->metadata)
1760 		ptr->size += strlen(ptr->metadata) + 1;
1761 	return GF_OK;
1762 }
1763 #endif //GPAC_DISABLE_ISOM_WRITE
1764 
adaf_box_new()1765 GF_Box *adaf_box_new()
1766 {
1767 	ISOM_DECL_BOX_ALLOC(GF_AdobeDRMAUFormatBox, GF_ISOM_BOX_TYPE_ADAF);
1768 	return (GF_Box *)tmp;
1769 }
1770 
adaf_box_del(GF_Box * s)1771 void adaf_box_del(GF_Box *s)
1772 {
1773 	gf_free(s);
1774 }
1775 
adaf_box_read(GF_Box * s,GF_BitStream * bs)1776 GF_Err adaf_box_read(GF_Box *s, GF_BitStream *bs)
1777 {
1778 	GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox*)s;
1779 
1780 	ISOM_DECREASE_SIZE(ptr, 3);
1781 	ptr->selective_enc = gf_bs_read_u8(bs);
1782 	gf_bs_read_u8(bs);//resersed
1783 	ptr->IV_length = gf_bs_read_u8(bs);
1784 	return GF_OK;
1785 }
1786 
1787 #ifndef GPAC_DISABLE_ISOM_WRITE
1788 
adaf_box_write(GF_Box * s,GF_BitStream * bs)1789 GF_Err adaf_box_write(GF_Box *s, GF_BitStream *bs)
1790 {
1791 	GF_Err e;
1792 	GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox *) s;
1793 	if (!s) return GF_BAD_PARAM;
1794 	e = gf_isom_full_box_write(s, bs);
1795 	if (e) return e;
1796 
1797 	gf_bs_write_u8(bs, ptr->selective_enc);
1798 	gf_bs_write_u8(bs, 0x0);
1799 	gf_bs_write_u8(bs, ptr->IV_length);
1800 	return GF_OK;
1801 }
1802 
adaf_box_size(GF_Box * s)1803 GF_Err adaf_box_size(GF_Box *s)
1804 {
1805 	GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox*)s;
1806 	ptr->size += 3;
1807 	return GF_OK;
1808 }
1809 #endif //GPAC_DISABLE_ISOM_WRITE
1810 
1811 
1812 #endif /*GPAC_DISABLE_ISOM*/
1813