/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: Jean Le Feuvre, Cyril Concolato
 *			Copyright (c) Telecom ParisTech 2005-2025
 *					All rights reserved
 *
 *  This file is part of GPAC / ISO Media File Format sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <gpac/internal/isomedia_dev.h>

#ifndef GPAC_DISABLE_ISOM

/* ProtectionInfo Box */
GF_Box *sinf_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ProtectionSchemeInfoBox, GF_ISOM_BOX_TYPE_SINF);
	return (GF_Box *)tmp;
}

void sinf_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err sinf_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_ProtectionSchemeInfoBox *ptr = (GF_ProtectionSchemeInfoBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_FRMA:
		BOX_FIELD_ASSIGN(original_format, GF_OriginalFormatBox)
		break;
	case GF_ISOM_BOX_TYPE_SCHM:
		BOX_FIELD_ASSIGN(scheme_type, GF_SchemeTypeBox)
		break;
	case GF_ISOM_BOX_TYPE_SCHI:
		BOX_FIELD_ASSIGN(info, GF_SchemeInformationBox)
		break;
	}
	return GF_OK;
}

GF_Err sinf_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err sinf_box_write(GF_Box *s, GF_BitStream *bs)
{
	return  gf_isom_box_write_header(s, bs);
}

GF_Err sinf_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_ProtectionSchemeInfoBox *ptr = (GF_ProtectionSchemeInfoBox *)s;
	gf_isom_check_position(s, (GF_Box *)ptr->original_format, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->scheme_type, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->info, &pos);
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

/* OriginalFormat Box */
GF_Box *frma_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_OriginalFormatBox, GF_ISOM_BOX_TYPE_FRMA);
	return (GF_Box *)tmp;
}

void frma_box_del(GF_Box *s)
{
	GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}

GF_Err frma_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	ptr->data_format = gf_bs_read_u32(bs);
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err frma_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	if (ptr->gnr_type)
		gf_bs_write_u32(bs, ptr->gnr_type);
	else
		gf_bs_write_u32(bs, ptr->data_format);
	return GF_OK;
}

GF_Err frma_box_size(GF_Box *s)
{
	GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s;
	ptr->size += 4;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

/* SchemeType Box */
GF_Box *schm_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SchemeTypeBox, GF_ISOM_BOX_TYPE_SCHM);
	return (GF_Box *)tmp;
}

void schm_box_del(GF_Box *s)
{
	GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;
	if (ptr == NULL) return;
	if (ptr->URI) gf_free(ptr->URI);
	gf_free(ptr);
}

GF_Err schm_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s;

	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->scheme_type = gf_bs_read_u32(bs);
	ptr->scheme_version = gf_bs_read_u32(bs);

	if (ptr->size && (ptr->flags & 0x000001)) {
		u32 len = (u32) (ptr->size);
		ptr->URI = (char*)gf_malloc(sizeof(char)*(len+1));
		if (!ptr->URI) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->URI, len);
		ptr->URI[len] = 0;
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err schm_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u32(bs, ptr->scheme_type);
	gf_bs_write_u32(bs, ptr->scheme_version);
	if (ptr->flags & 0x000001) {
		if (ptr->URI)
			gf_bs_write_data(bs, ptr->URI, (u32) strlen(ptr->URI)+1);
		else
			gf_bs_write_u8(bs, 0);
	}
	return GF_OK;
}

GF_Err schm_box_size(GF_Box *s)
{
	GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *) s;
	if (!s) return GF_BAD_PARAM;
	ptr->size += 8;
	if (ptr->flags & 0x000001) ptr->size += 1 + (ptr->URI ? strlen(ptr->URI) : 0);
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

/* SchemeInformation Box */
GF_Box *schi_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SchemeInformationBox, GF_ISOM_BOX_TYPE_SCHI);
	return (GF_Box *)tmp;
}

void schi_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err schi_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_IKMS:
		BOX_FIELD_ASSIGN(ikms, GF_ISMAKMSBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_ISFM:
		BOX_FIELD_ASSIGN(isfm, GF_ISMASampleFormatBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_ISLT:
		BOX_FIELD_ASSIGN(islt, GF_ISMACrypSaltBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_ODKM:
		BOX_FIELD_ASSIGN(odkm, GF_OMADRMKMSBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_TENC:
		BOX_FIELD_ASSIGN(tenc, GF_TrackEncryptionBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_ADKM:
		BOX_FIELD_ASSIGN(adkm, GF_AdobeDRMKeyManagementSystemBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_UUID:
		if (((GF_UUIDBox*)a)->internal_4cc==GF_ISOM_BOX_UUID_TENC) {
			BOX_FIELD_ASSIGN(piff_tenc, GF_PIFFTrackEncryptionBox)
			return GF_OK;
		} else {
			return GF_OK;
		}
	}
	return GF_OK;
}

GF_Err schi_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err schi_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_write_header(s, bs);
}

GF_Err schi_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_SchemeInformationBox *ptr = (GF_SchemeInformationBox *)s;

	gf_isom_check_position(s, (GF_Box *)ptr->ikms, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->isfm, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->islt, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->odkm, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->tenc, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->adkm, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->piff_tenc, &pos);
	return GF_OK;
}

#endif /*GPAC_DISABLE_ISOM_WRITE*/

/* ISMAKMS Box */
GF_Box *iKMS_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ISMAKMSBox, GF_ISOM_BOX_TYPE_IKMS);
	return (GF_Box *)tmp;
}

void iKMS_box_del(GF_Box *s)
{
	GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
	if (ptr == NULL) return;
	if (ptr->URI) gf_free(ptr->URI);
	gf_free(ptr);
}

GF_Err iKMS_box_read(GF_Box *s, GF_BitStream *bs)
{
	u32 len;
	GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;

	len = (u32) (ptr->size);
	if (len) {
		ptr->URI = (char*) gf_malloc(sizeof(char)*len);
		if (!ptr->URI) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->URI, len);
		ptr->URI[len-1] = 0;
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err iKMS_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->URI)
		gf_bs_write_data(bs, ptr->URI, (u32) strlen(ptr->URI));
	gf_bs_write_u8(bs, 0);
	return GF_OK;
}

GF_Err iKMS_box_size(GF_Box *s)
{
	GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s;
	ptr->size += (ptr->URI ? strlen(ptr->URI) : 0) + 1;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

/* ISMASampleFormat Box */
GF_Box *iSFM_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ISMASampleFormatBox, GF_ISOM_BOX_TYPE_ISFM);
	return (GF_Box *)tmp;
}

void iSFM_box_del(GF_Box *s)
{
	GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}


GF_Err iSFM_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;

	ISOM_DECREASE_SIZE(ptr, 3);
	ptr->selective_encryption = gf_bs_read_int(bs, 1);
	gf_bs_read_int(bs, 7);
	ptr->key_indicator_length = gf_bs_read_u8(bs);
	ptr->IV_length = gf_bs_read_u8(bs);
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err iSFM_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_int(bs, ptr->selective_encryption, 1);
	gf_bs_write_int(bs, 0, 7);
	gf_bs_write_u8(bs, ptr->key_indicator_length);
	gf_bs_write_u8(bs, ptr->IV_length);
	return GF_OK;
}

GF_Err iSFM_box_size(GF_Box *s)
{
	GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s;
	ptr->size += 3;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/

/* ISMASampleFormat Box */
GF_Box *iSLT_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ISMACrypSaltBox, GF_ISOM_BOX_TYPE_ISLT);
	return (GF_Box *)tmp;
}

void iSLT_box_del(GF_Box *s)
{
	GF_ISMACrypSaltBox *ptr = (GF_ISMACrypSaltBox *)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}


GF_Err iSLT_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_ISMACrypSaltBox *ptr = (GF_ISMACrypSaltBox *)s;
	if (ptr == NULL) return GF_BAD_PARAM;
	ISOM_DECREASE_SIZE(ptr, 8);
	ptr->salt = gf_bs_read_u64(bs);
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err iSLT_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ISMACrypSaltBox *ptr = (GF_ISMACrypSaltBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u64(bs, ptr->salt);
	return GF_OK;
}

GF_Err iSLT_box_size(GF_Box *s)
{
	s->size += 8;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/



/* OMADRMCommonHeader Box */
GF_Box *ohdr_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_OMADRMCommonHeaderBox, GF_ISOM_BOX_TYPE_OHDR);
	tmp->child_boxes = gf_list_new();
	return (GF_Box *)tmp;
}

void ohdr_box_del(GF_Box *s)
{
	GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;
	if (ptr == NULL) return;
	if (ptr->ContentID) gf_free(ptr->ContentID);
	if (ptr->RightsIssuerURL) gf_free(ptr->RightsIssuerURL);
	if (ptr->TextualHeaders) gf_free(ptr->TextualHeaders);
	gf_free(ptr);
}

GF_Err ohdr_box_read(GF_Box *s, GF_BitStream *bs)
{
	u16 cid_len, ri_len;
	GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox*)s;

	ISOM_DECREASE_SIZE(ptr, (1+1+8+2+2+2) );
	ptr->EncryptionMethod = gf_bs_read_u8(bs);
	ptr->PaddingScheme = gf_bs_read_u8(bs);
	ptr->PlaintextLength = gf_bs_read_u64(bs);
	cid_len = gf_bs_read_u16(bs);
	ri_len = gf_bs_read_u16(bs);
	ptr->TextualHeadersLen = gf_bs_read_u16(bs);

	if (ptr->size<cid_len+ri_len+ptr->TextualHeadersLen) return GF_ISOM_INVALID_FILE;

	if (cid_len) {
		ptr->ContentID = (char *)gf_malloc(sizeof(char)*(cid_len+1));
		if (!ptr->ContentID) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->ContentID, cid_len);
		ptr->ContentID[cid_len]=0;
	}

	if (ri_len) {
		ptr->RightsIssuerURL = (char *)gf_malloc(sizeof(char)*(ri_len+1));
		if (!ptr->RightsIssuerURL) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->RightsIssuerURL, ri_len);
		ptr->RightsIssuerURL[ri_len]=0;
	}

	if (ptr->TextualHeadersLen) {
		ptr->TextualHeaders = (char *)gf_malloc(sizeof(char)*(ptr->TextualHeadersLen+1));
		if (!ptr->TextualHeaders) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen);
		ptr->TextualHeaders[ptr->TextualHeadersLen] = 0;
	}

	ISOM_DECREASE_SIZE(ptr, (cid_len+ri_len+ptr->TextualHeadersLen) );

	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err ohdr_box_write(GF_Box *s, GF_BitStream *bs)
{
	u16 cid_len, ri_len;
	GF_Err e;
	GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->EncryptionMethod);
	gf_bs_write_u8(bs, ptr->PaddingScheme);
	gf_bs_write_u64(bs, ptr->PlaintextLength);

	cid_len = ptr->ContentID ? (u16) strlen(ptr->ContentID) : 0;
	gf_bs_write_u16(bs, cid_len);
	ri_len = ptr->RightsIssuerURL ? (u16) strlen(ptr->RightsIssuerURL) : 0;
	gf_bs_write_u16(bs, ri_len);
	gf_bs_write_u16(bs, ptr->TextualHeadersLen);

	if (cid_len) gf_bs_write_data(bs, ptr->ContentID, (u32) strlen(ptr->ContentID));
	if (ri_len) gf_bs_write_data(bs, ptr->RightsIssuerURL, (u32) strlen(ptr->RightsIssuerURL));
	if (ptr->TextualHeadersLen) gf_bs_write_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen);

	ISOM_DECREASE_SIZE(ptr, (cid_len+ri_len+ptr->TextualHeadersLen) );
	return GF_OK;
}

GF_Err ohdr_box_size(GF_Box *s)
{
	GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)s;
	ptr->size += 1+1+8+2+2+2;
	if (ptr->ContentID) ptr->size += strlen(ptr->ContentID);
	if (ptr->RightsIssuerURL) ptr->size += strlen(ptr->RightsIssuerURL);
	if (ptr->TextualHeadersLen) ptr->size += ptr->TextualHeadersLen;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


/* OMADRMGroupID Box */
GF_Box *grpi_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_OMADRMGroupIDBox, GF_ISOM_BOX_TYPE_GRPI);
	return (GF_Box *)tmp;
}

void grpi_box_del(GF_Box *s)
{
	GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
	if (ptr == NULL) return;
	if (ptr->GroupID) gf_free(ptr->GroupID);
	if (ptr->GroupKey) gf_free(ptr->GroupKey);
	gf_free(ptr);
}

GF_Err grpi_box_read(GF_Box *s, GF_BitStream *bs)
{
	u16 gid_len;
	GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox*)s;

	ISOM_DECREASE_SIZE(ptr, (1+2+2) );
	gid_len = gf_bs_read_u16(bs);
	ptr->GKEncryptionMethod = gf_bs_read_u8(bs);
	ptr->GKLength = gf_bs_read_u16(bs);

	if (ptr->size<gid_len+ptr->GKLength) return GF_ISOM_INVALID_FILE;

	ptr->GroupID = gf_malloc(sizeof(char)*(gid_len+1));
	if (!ptr->GroupID) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, ptr->GroupID, gid_len);
	ptr->GroupID[gid_len]=0;

	ptr->GroupKey = (char *)gf_malloc(sizeof(char)*ptr->GKLength);
	if (!ptr->GroupKey) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, ptr->GroupKey, ptr->GKLength);
	ISOM_DECREASE_SIZE(ptr, (gid_len+ptr->GKLength) );
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err grpi_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u16 gid_len;
	GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gid_len = ptr->GroupID ? (u16) strlen(ptr->GroupID) : 0;
	gf_bs_write_u16(bs, gid_len);
	gf_bs_write_u8(bs, ptr->GKEncryptionMethod);
	gf_bs_write_u16(bs, ptr->GKLength);
	gf_bs_write_data(bs, ptr->GroupID, gid_len);
	gf_bs_write_data(bs, ptr->GroupKey, ptr->GKLength);
	return GF_OK;
}

GF_Err grpi_box_size(GF_Box *s)
{
	GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s;
	ptr->size += 2+2+1 + ptr->GKLength;
	if (ptr->GroupID) ptr->size += strlen(ptr->GroupID);
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/




/* OMADRMMutableInformation Box */
GF_Box *mdri_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_OMADRMMutableInformationBox, GF_ISOM_BOX_TYPE_MDRI);
	return (GF_Box *)tmp;
}

void mdri_box_del(GF_Box *s)
{
	GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s;
	if (ptr == NULL) return;
	gf_free(ptr);
}

GF_Err mdri_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err mdri_box_write(GF_Box *s, GF_BitStream *bs)
{
//	GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s;
	GF_Err e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	return GF_OK;
}

GF_Err mdri_box_size(GF_Box *s)
{
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/


/* OMADRMTransactionTracking Box */
GF_Box *odtt_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_OMADRMTransactionTrackingBox, GF_ISOM_BOX_TYPE_ODTT);
	return (GF_Box *)tmp;
}

void odtt_box_del(GF_Box *s)
{
	GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s;
	gf_free(ptr);
}

GF_Err odtt_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox *)s;

	gf_bs_read_data(bs, ptr->TransactionID, 16);
	ISOM_DECREASE_SIZE(ptr, 16);
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err odtt_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_data(bs, ptr->TransactionID, 16);
	return GF_OK;
}

GF_Err odtt_box_size(GF_Box *s)
{
	s->size += 16;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/



/* OMADRMRightsObject Box */
GF_Box *odrb_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_OMADRMRightsObjectBox, GF_ISOM_BOX_TYPE_ODRB);
	return (GF_Box *)tmp;
}

void odrb_box_del(GF_Box *s)
{
	GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox*)s;
	if (ptr->oma_ro) gf_free(ptr->oma_ro);
	gf_free(ptr);
}

GF_Err odrb_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;

	ptr->oma_ro_size = (u32) ptr->size;
	ptr->oma_ro = (char*) gf_malloc(sizeof(char)*ptr->oma_ro_size);
	if (!ptr->oma_ro) return GF_OUT_OF_MEM;
	gf_bs_read_data(bs, ptr->oma_ro, ptr->oma_ro_size);
	ptr->size = 0;
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err odrb_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	gf_bs_write_data(bs, ptr->oma_ro, ptr->oma_ro_size);
	return GF_OK;
}

GF_Err odrb_box_size(GF_Box *s)
{
	GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox *)s;
	s->size += ptr->oma_ro_size;
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/




/* OMADRMKMS Box */
GF_Box *odkm_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_OMADRMKMSBox, GF_ISOM_BOX_TYPE_ODKM);
	return (GF_Box *)tmp;
}

void odkm_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err odkm_Add(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_OHDR:
		BOX_FIELD_ASSIGN(hdr, GF_OMADRMCommonHeaderBox)
		return GF_OK;
	case GF_ISOM_BOX_TYPE_ODAF:
		BOX_FIELD_ASSIGN(fmt, GF_OMADRMAUFormatBox)
		return GF_OK;
	}
	return GF_OK;
}

GF_Err odkm_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err odkm_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_full_box_write(s, bs);
}

GF_Err odkm_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_OMADRMKMSBox *ptr = (GF_OMADRMKMSBox *)s;
	gf_isom_check_position(s, (GF_Box *)ptr->hdr, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->fmt, &pos);
	return GF_OK;
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/




GF_Box *pssh_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_ProtectionSystemHeaderBox, GF_ISOM_BOX_TYPE_PSSH);
	return (GF_Box *)tmp;
}

void pssh_box_del(GF_Box *s)
{
	GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*)s;
	if (ptr == NULL) return;
	if (ptr->private_data) gf_free(ptr->private_data);
	if (ptr->KIDs) gf_free(ptr->KIDs);
	gf_free(ptr);
}

GF_Err pssh_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *)s;

	gf_bs_read_data(bs, (char *) ptr->SystemID, 16);
	ISOM_DECREASE_SIZE(ptr, 16);
	if (ptr->version > 0) {
		ptr->KID_count = gf_bs_read_u32(bs);
		ISOM_DECREASE_SIZE(ptr, 4);
		if (ptr->KID_count) {
			u32 i;
			if (ptr->size / sizeof(bin128) < ptr->KID_count)
				return GF_ISOM_INVALID_FILE;
			ptr->KIDs = gf_malloc(ptr->KID_count*sizeof(bin128));
			if (!ptr->KIDs)
				return GF_OUT_OF_MEM;
			for (i=0; i<ptr->KID_count; i++) {
				gf_bs_read_data(bs, (char *) ptr->KIDs[i], 16);
				ISOM_DECREASE_SIZE(ptr, 16);
			}
		}
	}
	ptr->private_data_size = gf_bs_read_u32(bs);
	ISOM_DECREASE_SIZE(ptr, 4);
	if (ptr->private_data_size) {
		if (ptr->size < ptr->private_data_size)
			return GF_ISOM_INVALID_FILE;
		ptr->private_data = gf_malloc(sizeof(char)*ptr->private_data_size);
		if (!ptr->private_data)
			return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, (char *) ptr->private_data, ptr->private_data_size);
		ISOM_DECREASE_SIZE(ptr, ptr->private_data_size);
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err pssh_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_data(bs, (char *) ptr->SystemID, 16);
	if (ptr->version > 0) {
		u32 i;
		gf_bs_write_u32(bs, ptr->KID_count);
		for (i=0; i<ptr->KID_count; i++)
			gf_bs_write_data(bs, (char *) ptr->KIDs[i], 16);
	}
	if (ptr->private_data) {
		gf_bs_write_u32(bs, ptr->private_data_size);
		gf_bs_write_data(bs, (char *) ptr->private_data, ptr->private_data_size);
	} else
		gf_bs_write_u32(bs, 0);
	return GF_OK;
}

GF_Err pssh_box_size(GF_Box *s)
{
	GF_ProtectionSystemHeaderBox *ptr = (GF_ProtectionSystemHeaderBox*)s;

	if (ptr->KID_count && !ptr->version) {
		ptr->version = 1;
	}

	ptr->size += 16;
	if (ptr->version) ptr->size += 4 + 16*ptr->KID_count;
	ptr->size += 4 + (ptr->private_data ? ptr->private_data_size : 0);
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE


GF_Box *tenc_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_TrackEncryptionBox, GF_ISOM_BOX_TYPE_TENC);
	return (GF_Box *)tmp;
}

void tenc_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err tenc_box_read(GF_Box *s, GF_BitStream *bs)
{
	u8 iv_size;
	GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*)s;

	ISOM_DECREASE_SIZE(ptr, 3);

	gf_bs_read_u8(bs); //reserved

	if (!ptr->version) {
		gf_bs_read_u8(bs); //reserved
	} else if (ptr->version==1) {
		ptr->crypt_byte_block = gf_bs_read_int(bs, 4);
		ptr->skip_byte_block = gf_bs_read_int(bs, 4);
	} else {
		ptr->crypt_byte_block = gf_bs_read_u32(bs);
		ptr->skip_byte_block = gf_bs_read_u32(bs);
		ISOM_DECREASE_SIZE(ptr, 7);
	}
	ptr->isProtected = gf_bs_read_u8(bs);


	ISOM_DECREASE_SIZE(ptr, 17);

	ptr->key_info[0] = 0;
	ptr->key_info[1] = 0;
	ptr->key_info[2] = 0;
	ptr->key_info[3] = iv_size = gf_bs_read_u8(bs);
	gf_bs_read_data(bs, ptr->key_info+4, 16);
	if (!iv_size && ptr->isProtected) {
		ISOM_DECREASE_SIZE(ptr, 1);
		iv_size = ptr->key_info[20] = gf_bs_read_u8(bs);
		ISOM_DECREASE_SIZE(ptr, ptr->key_info[20]);
		if ((iv_size!=8) && (iv_size!=16)) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid constant IV size %d, must be 8 or 16\n", (u32) iv_size));
			ptr->key_info[20] = 16;
			return GF_NON_COMPLIANT_BITSTREAM;
		}
		gf_bs_read_data(bs, ptr->key_info+21, iv_size);
	}
	else if ((iv_size!=0) && (iv_size!=8) && (iv_size!=16)) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Invalid IV size %d, must be 0, 8 or 16\n", (u32) iv_size));
		return GF_NON_COMPLIANT_BITSTREAM;
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err tenc_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u8(bs, 0); //reserved

	if (!ptr->version) {
		gf_bs_write_u8(bs, 0); //reserved
	} else {
		if (ptr->version==1) {
			gf_bs_write_int(bs, ptr->crypt_byte_block, 4);
			gf_bs_write_int(bs, ptr->skip_byte_block, 4);
		} else {
			gf_bs_write_u32(bs, ptr->crypt_byte_block);
			gf_bs_write_u32(bs, ptr->skip_byte_block);
		}
	}
	gf_bs_write_u8(bs, ptr->isProtected);

	gf_bs_write_u8(bs, ptr->key_info[3]);
	gf_bs_write_data(bs, ptr->key_info + 4, 16);
	if ((ptr->isProtected == 1) && !ptr->key_info[3]) {
		gf_bs_write_u8(bs, ptr->key_info[20]);
		gf_bs_write_data(bs, ptr->key_info + 21, ptr->key_info[20]);
	}
	return GF_OK;
}

GF_Err tenc_box_size(GF_Box *s)
{
	GF_TrackEncryptionBox *ptr = (GF_TrackEncryptionBox*)s;
	ptr->size += 3;
	if ((ptr->crypt_byte_block>15) || (ptr->skip_byte_block>15)) {
		ptr->version=2;
		ptr->size += 7;
	}

	ptr->size += 17;
	if ((ptr->isProtected == 1) && ! ptr->key_info[3]) {
		ptr->size += 1 + ptr->key_info[20];
	}
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE

GF_Box *piff_tenc_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_PIFFTrackEncryptionBox, GF_ISOM_BOX_TYPE_UUID);
	tmp->internal_4cc = GF_ISOM_BOX_UUID_TENC;
	return (GF_Box *)tmp;
}

void piff_tenc_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err piff_tenc_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*)s;

	ISOM_DECREASE_SIZE(ptr, 4);
	//PIFF TENC extends UUID and fullbox
	ptr->version = gf_bs_read_u8(bs);
	ptr->flags = gf_bs_read_u24(bs);

	ISOM_DECREASE_SIZE(ptr, 20);
	ptr->AlgorithmID = gf_bs_read_int(bs, 24);
	ptr->key_info[0] = 0;
	ptr->key_info[1] = 0;
	ptr->key_info[2] = 0;
	ptr->key_info[3] = gf_bs_read_u8(bs);
	gf_bs_read_data(bs, ptr->key_info+4, 16);
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err piff_tenc_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox *) s;
	if (!s) return GF_BAD_PARAM;

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->version);
	gf_bs_write_u24(bs, ptr->flags);

	gf_bs_write_int(bs, ptr->AlgorithmID, 24);
	gf_bs_write_u8(bs, ptr->key_info[3]);
	gf_bs_write_data(bs, ptr->key_info+4, 16);
	return GF_OK;
}

GF_Err piff_tenc_box_size(GF_Box *s)
{
	GF_PIFFTrackEncryptionBox *ptr = (GF_PIFFTrackEncryptionBox*)s;
	ptr->size += 24;
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE


GF_Box *piff_psec_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleEncryptionBox, GF_ISOM_BOX_TYPE_UUID);
	tmp->internal_4cc = GF_ISOM_BOX_UUID_PSEC;
	tmp->piff_type = 1;
	return (GF_Box *)tmp;
}

void piff_psec_box_del(GF_Box *s)
{
	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
	if (ptr->samp_aux_info) {
		u32 i, count=gf_list_count(ptr->samp_aux_info);
		for (i=0; i<count; i++) {
			GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
			if (sai) gf_isom_cenc_samp_aux_info_del(sai);
		}
		gf_list_del(ptr->samp_aux_info);
	}
	gf_free(s);
}


GF_Err piff_psec_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;

	ISOM_DECREASE_SIZE(ptr, 4);
	//PIFF PSEC extends UUID and fullbox
	ptr->version = gf_bs_read_u8(bs);
	ptr->flags = gf_bs_read_u24(bs);

	if (ptr->flags & 1) {
		ISOM_DECREASE_SIZE(ptr, 20);
		ptr->AlgorithmID = gf_bs_read_int(bs, 24);
		ptr->IV_size = gf_bs_read_u8(bs);
		gf_bs_read_data(bs, (char *) ptr->KID, 16);
	}
	if (ptr->IV_size == 0)
		ptr->IV_size = 8; //default to 8

	ptr->bs_offset = gf_bs_get_position(bs);

	/*u32 sample_count = */gf_bs_read_u32(bs);
	ISOM_DECREASE_SIZE(ptr, 4);
	if (ptr->IV_size != 8 && ptr->IV_size != 16) {
		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));
		return GF_BAD_PARAM;
	}
	//as for senc, we skip parsing of the box until we have all saiz/saio info
	gf_bs_skip_bytes(bs, ptr->size);
	ptr->size = 0;
	ptr->load_needed = GF_TRUE;
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err store_senc_info(GF_SampleEncryptionBox *ptr, GF_BitStream *bs)
{
	GF_Err e;
	u64 pos, new_pos;
	if (!ptr->cenc_saio) return GF_OK;

	pos = gf_bs_get_position(bs);
	if (pos>0xFFFFFFFFULL) {
		if (ptr->cenc_saio && !ptr->cenc_saio->version) {
			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"));
			return GF_BAD_PARAM;
		}
	}
	e = gf_bs_seek(bs, ptr->cenc_saio->offset_first_offset_field);
	if (e) return e;
	//force using version 1 for saio box i.e offset has 64 bits
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
	if (ptr->traf) {
		new_pos = pos - ptr->traf->moof_start_in_bs;
	} else
#endif
	{
		new_pos = pos;
	}

	if (ptr->cenc_saio->offsets) {
		u32 i;
		u64 old_offset = ptr->cenc_saio->offsets[0];
		for (i=0; i<ptr->cenc_saio->entry_count; i++) {
			if (ptr->cenc_saio->version) {
				gf_bs_write_u64(bs, new_pos + ptr->cenc_saio->offsets[i] - old_offset);
			} else {
				gf_bs_write_u32(bs, (u32) (new_pos + ptr->cenc_saio->offsets[i] - old_offset));
			}
			ptr->cenc_saio->offsets[i] = new_pos + ptr->cenc_saio->offsets[i] - old_offset;
		}
	} else {
		if (ptr->cenc_saio->version) {
			gf_bs_write_u64(bs, new_pos);
		} else {
			gf_bs_write_u32(bs, (u32) new_pos);
		}
	}

	return gf_bs_seek(bs, pos);
}

GF_Err piff_psec_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 sample_count;
	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *) s;
	if (!s) return GF_BAD_PARAM;

	sample_count = gf_list_count(ptr->samp_aux_info);
	if (!sample_count) {
		ptr->size = 0;
		return GF_OK;
	}
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->version);
	gf_bs_write_u24(bs, ptr->flags);

	if (ptr->flags & 1) {
		gf_bs_write_int(bs, ptr->AlgorithmID, 24);
		gf_bs_write_u8(bs, ptr->IV_size);
		gf_bs_write_data(bs, (char *) ptr->KID, 16);
	}
	sample_count = gf_list_count(ptr->samp_aux_info);
	gf_bs_write_u32(bs, sample_count);
	if (sample_count) {
		u32 i;
		e = store_senc_info((GF_SampleEncryptionBox *)ptr, bs);
		if (e) return e;

		for (i = 0; i < sample_count; i++) {
			GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
			if (! sai->cenc_data_size) continue;
			gf_bs_write_data(bs, (char *)sai->cenc_data, sai->cenc_data_size);
		}
	}
	return GF_OK;
}

GF_Err piff_psec_box_size(GF_Box *s)
{
	u32 i, sample_count;
	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox*)s;

	sample_count = gf_list_count(ptr->samp_aux_info);
	if (!sample_count) {
		ptr->size = 0;
		return GF_OK;
	}

	ptr->size += 4;
	if (ptr->flags & 1) {
		ptr->size += 20;
	}
	ptr->size += 4;

	for (i = 0; i < sample_count; i++) {
		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
		if (! sai->cenc_data_size) continue;
		ptr->size += sai->cenc_data_size;
	}
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE


GF_Box *piff_pssh_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_PIFFProtectionSystemHeaderBox, GF_ISOM_BOX_TYPE_UUID);
	tmp->internal_4cc = GF_ISOM_BOX_UUID_PSSH;
	return (GF_Box *)tmp;
}

void piff_pssh_box_del(GF_Box *s)
{
	GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s;
	if (ptr->private_data) gf_free(ptr->private_data);
	gf_free(s);
}

GF_Err piff_pssh_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s;

	ISOM_DECREASE_SIZE(ptr, 24);
	//PIFF PSSH extends UUID and fullbox
	ptr->version = gf_bs_read_u8(bs);
	ptr->flags = gf_bs_read_u24(bs);
	gf_bs_read_data(bs, (char *) ptr->SystemID, 16);
	ptr->private_data_size = gf_bs_read_u32(bs);

	if (ptr->size < ptr->private_data_size)
		return GF_ISOM_INVALID_FILE;
	ptr->private_data = gf_malloc(sizeof(char)*ptr->private_data_size);
	if (!ptr->private_data)
		return GF_OUT_OF_MEM;

	ISOM_DECREASE_SIZE(ptr, ptr->private_data_size);
	gf_bs_read_data(bs, (char *) ptr->private_data, ptr->private_data_size);
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err piff_pssh_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox *) s;
	GF_Err e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	gf_bs_write_u8(bs, ptr->version);
	gf_bs_write_u24(bs, ptr->flags);

	gf_bs_write_data(bs, (char *) ptr->SystemID, 16);
	gf_bs_write_u32(bs, ptr->private_data_size);
	gf_bs_write_data(bs, (char *) ptr->private_data, ptr->private_data_size);
	return GF_OK;
}

GF_Err piff_pssh_box_size(GF_Box *s)
{
	GF_PIFFProtectionSystemHeaderBox *ptr = (GF_PIFFProtectionSystemHeaderBox*)s;

	ptr->size += 24 + ptr->private_data_size;
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE

GF_Box *senc_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_SampleEncryptionBox, GF_ISOM_BOX_TYPE_SENC);
	return (GF_Box *)tmp;
}

void senc_box_del(GF_Box *s)
{
	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
	while (1) {
		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_pop_back(ptr->samp_aux_info);
		if (!sai) break;
		gf_isom_cenc_samp_aux_info_del(sai);
	}
	if (ptr->samp_aux_info) gf_list_del(ptr->samp_aux_info);
	gf_free(s);
}

#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
GF_Err senc_Parse(GF_BitStream *bs, GF_TrackBox *trak, GF_TrackFragmentBox *traf, GF_SampleEncryptionBox *senc, u32 max_nb_samples)
#else
GF_Err senc_Parse(GF_BitStream *bs, GF_TrackBox *trak, void *traf, GF_SampleEncryptionBox *senc, u32 max_nb_samples)
#endif
{
	GF_Err e;
	Bool parse_failed = GF_FALSE;
	u32 i, count, sample_number;
	u32 senc_size = (u32) senc->size;
	u32 subs_size = 0, def_IV_size;
	u64 pos = gf_bs_get_position(bs);
	Bool do_warn = GF_TRUE;
	Bool use_multikey = GF_FALSE;
	Bool patch_subsamples_present = GF_FALSE;

#ifdef	GPAC_DISABLE_ISOM_FRAGMENTS
	if (!traf)
		return GF_BAD_PARAM;
#endif

	//BOX + version/flags
	if (senc_size<12) return GF_BAD_PARAM;
	senc_size -= 12;

	if (senc->piff_type==1) {
		//UUID
		if (senc_size<16) return GF_BAD_PARAM;
		senc_size -= 16;
	} else if (!senc->piff_type) {
		if (senc->version==1)
			use_multikey = GF_TRUE;
	}
	if (senc->flags & 2) subs_size = 8;

	if (senc_size<4) return GF_BAD_PARAM;
	if (!max_nb_samples) {
#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
		if (traf) {
			i=0;
			GF_TrackFragmentRunBox *trun;
			while ((trun = gf_list_enum(traf->TrackRuns, &i))) {
				max_nb_samples += trun->nb_samples;
			}
		} else
#endif
		if (trak->Media->information->sampleTable->SampleSize)
			max_nb_samples = trak->Media->information->sampleTable->SampleSize->sampleCount;
	}

	sample_number = 1;
#ifndef	GPAC_DISABLE_ISOM_FRAGMENTS
	if (trak) sample_number += trak->sample_count_at_seg_start;
#endif

	gf_bs_seek(bs, senc->bs_offset);

	count = gf_bs_read_u32(bs);
	senc_size -= 4;

	def_IV_size = 0;
	//check the target size if we have one subsample
	if (senc_size >= count * (16 + subs_size)) {
		def_IV_size = 16;
	}
	else if (senc_size >= count * (8 + subs_size)) {
		def_IV_size = 8;
	}
	else if (senc_size >= count * (subs_size)) {
		def_IV_size = 0;
	}

	if (gf_opts_get_bool("core", "piff-force-subsamples") && !(senc->flags & 0x00000002))
		patch_subsamples_present = GF_TRUE;

	if (!senc->samp_aux_info) senc->samp_aux_info = gf_list_new();
	for (i=0; i<count; i++) {
		const u8 *key_info=NULL;
		u32 key_info_size=0;
		Bool is_encrypted;
		GF_CENCSampleAuxInfo *sai;
		u8 IV_size=0;
		//u32 nb_keys = 0;
		u32 nb_bytes_subsample = 6;
		u32 nb_subs_bits = 16;

		if (!max_nb_samples)
			break;

		GF_SAFEALLOC(sai, GF_CENCSampleAuxInfo);
		if (!sai) {
			gf_bs_seek(bs, pos);
			return GF_OUT_OF_MEM;
		}
		if (trak) {
			e = gf_isom_get_sample_cenc_info_internal(trak, traf, senc, sample_number, &is_encrypted, NULL, NULL, &key_info, &key_info_size);
			if (! key_info) {
				if (!key_info_size && is_encrypted) {
					GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isobmf] no key info and no associated IV size !\n" ));
					gf_free(sai);
					return GF_ISOM_INVALID_FILE;
				}
				IV_size = key_info_size; //piff default
				use_multikey = GF_FALSE;
				senc->piff_type = 2;
			} else if (use_multikey) {
				//nb_keys = key_info[1];
				//nb_keys <<= 8;
				//nb_keys |= key_info[2];
				nb_bytes_subsample = 8;
				nb_subs_bits = 32;
			} else {
				IV_size = key_info[3];
			}

			if (e) {
				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) ));
				gf_isom_cenc_samp_aux_info_del(sai);
				gf_bs_seek(bs, pos);
				if (trak->moov->mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG)
					return GF_OK;
				return e;
			}
		}
		//no init movie setup (segment dump/inspaction, assume default encrypted and 16 bytes IV
		else {
			if (do_warn) {
				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));
				do_warn = GF_FALSE;
			}
			is_encrypted = GF_TRUE;
			IV_size = def_IV_size;
		}
		if (senc_size < IV_size) {
			parse_failed = GF_TRUE;
			gf_isom_cenc_samp_aux_info_del(sai);
			break;
		}

		sample_number++;

		//subsample info is only signaled for encrypted samples
		if (is_encrypted) {
			u64 sai_start = gf_bs_get_position(bs);
			u32 nb_subs = 0;

			if (use_multikey) {
				u32 j;
				u32 nb_iv_init = gf_bs_read_u16(bs);
				for (j=0; j<nb_iv_init; j++) {
					u32 idx = gf_bs_read_u16(bs);
					IV_size = gf_cenc_key_info_get_iv_size(key_info, key_info_size, idx, NULL, NULL);
					if (!IV_size) {
						gf_isom_cenc_samp_aux_info_del(sai);
						GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isobmf] Failed to parse SENC box, invalid SAI multikey with IV size 0\n" ));
						gf_bs_seek(bs, pos);
						return GF_ISOM_INVALID_FILE;
					}
					gf_bs_skip_bytes(bs, IV_size);
				}

			} else {
				if (IV_size > 16) {
					gf_isom_cenc_samp_aux_info_del(sai);
					GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[isobmf] Failed to parse SENC box, invalid SAI size\n" ));
					gf_bs_seek(bs, pos);
					return GF_ISOM_INVALID_FILE;
				}
				if (IV_size) {
					gf_bs_skip_bytes(bs, IV_size);
				}
			}
			if (senc->flags & 0x00000002) {
				nb_subs = gf_bs_read_int(bs, nb_subs_bits);
			}

			sai->cenc_data_size = (u32) (gf_bs_get_position(bs) - sai_start);
			sai->cenc_data_size += nb_subs * nb_bytes_subsample;
			gf_bs_seek(bs, sai_start);

			if (!sai->cenc_data_size || (s32) senc_size < sai->cenc_data_size) {
				parse_failed = GF_TRUE;
				gf_isom_cenc_samp_aux_info_del(sai);
				break;
			}

			sai->cenc_data = gf_malloc(sizeof(u8) * sai->cenc_data_size);
			if (!sai->cenc_data) {
				gf_isom_cenc_samp_aux_info_del(sai);
				gf_bs_seek(bs, pos);
				return GF_OUT_OF_MEM;
			}
			gf_bs_read_data(bs, sai->cenc_data, sai->cenc_data_size);
			senc_size -= sai->cenc_data_size;

			if (patch_subsamples_present) {
				gf_bs_read_int(bs, nb_subs_bits);
			}
		} else {
			i--;
			sai->isNotProtected = 1;
		}

		if (senc->internal_4cc == GF_ISOM_BOX_UUID_PSEC) {
			sai->key_info_size = IV_size;
		} else {
			sai->key_info = key_info;
			sai->key_info_size = key_info_size;
		}
		gf_list_add(senc->samp_aux_info, sai);

		max_nb_samples--;
	}
	gf_bs_seek(bs, pos);
	if (parse_failed) {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[isobmf] cannot parse senc, missing IV/crypto state\n"));
	}
	return GF_OK;
}


GF_Err senc_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *)s;
	ISOM_DECREASE_SIZE(ptr, 4);
	//WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
	ptr->version = gf_bs_read_u8(bs);
	ptr->flags = gf_bs_read_u24(bs);

	ptr->bs_offset = gf_bs_get_position(bs);
	gf_bs_skip_bytes(bs, ptr->size);
	ptr->size = 0;
	ptr->load_needed = GF_TRUE;
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE


GF_Err senc_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	u32 i;
	u32 sample_count, nb_crypt_samples;
	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox *) s;

	sample_count = gf_list_count(ptr->samp_aux_info);
	//temp patch until we cleanup the spec...
	nb_crypt_samples = 0;
	for (i = 0; i < sample_count; i++) {
		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
		if (!sai->isNotProtected) nb_crypt_samples++;
	}
	if (!nb_crypt_samples) {
		ptr->size = 0;
		return GF_OK;
	}

	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	//WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
	gf_bs_write_u8(bs, ptr->version);
	gf_bs_write_u24(bs, ptr->flags);

	gf_bs_write_u32(bs, nb_crypt_samples);

	e = store_senc_info(ptr, bs);
	if (e) return e;

	for (i = 0; i < sample_count; i++) {
		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
		if (sai->isNotProtected || !sai->cenc_data_size)
			continue;
		gf_bs_write_data(bs, sai->cenc_data, sai->cenc_data_size);
	}
	return GF_OK;
}

GF_Err senc_box_size(GF_Box *s)
{
	u32 sample_count;
	u32 i, nb_crypt_samples;
	GF_SampleEncryptionBox *ptr = (GF_SampleEncryptionBox*)s;
	sample_count = gf_list_count(ptr->samp_aux_info);
	//temp patch until we cleanup the spec...
	nb_crypt_samples=0;
	for (i = 0; i < sample_count; i++) {
		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
		if (!sai->isNotProtected) nb_crypt_samples++;
	}

	if (!nb_crypt_samples) {
		ptr->size = 0;
		return GF_OK;
	}

	//WARNING - PSEC (UUID) IS TYPECASTED TO SENC (FULL BOX) SO WE CANNOT USE USUAL FULL BOX FUNCTIONS
	ptr->size += 4; //version and flags

	ptr->size += 4; //sample count
	for (i = 0; i < sample_count; i++) {
		GF_CENCSampleAuxInfo *sai = (GF_CENCSampleAuxInfo *)gf_list_get(ptr->samp_aux_info, i);
		if (sai->isNotProtected)
			continue;
		ptr->size += sai->cenc_data_size;
	}
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE

GF_Box *adkm_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_AdobeDRMKeyManagementSystemBox, GF_ISOM_BOX_TYPE_ADKM);
	tmp->version = 1;
	tmp->flags = 0;
	return (GF_Box *)tmp;
}

void adkm_box_del(GF_Box *s)
{
	GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
	if (!ptr) return;
	gf_free(s);
}

GF_Err adkm_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_AHDR:
		BOX_FIELD_ASSIGN(header, GF_AdobeDRMHeaderBox)
		break;
	case GF_ISOM_BOX_TYPE_ADAF:
		BOX_FIELD_ASSIGN(au_format, GF_AdobeDRMAUFormatBox)
		break;
	}
	return GF_OK;
}

GF_Err adkm_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err adkm_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_full_box_write(s, bs);
}

GF_Err adkm_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_AdobeDRMKeyManagementSystemBox *ptr = (GF_AdobeDRMKeyManagementSystemBox *)s;
	gf_isom_check_position(s, (GF_Box *)ptr->header, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->au_format, &pos);
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE

GF_Box *ahdr_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_AdobeDRMHeaderBox, GF_ISOM_BOX_TYPE_AHDR);
	tmp->version = 2;
	tmp->flags = 0;
	return (GF_Box *)tmp;
}

void ahdr_box_del(GF_Box *s)
{
	gf_free(s);
}


GF_Err ahdr_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_APRM:
		BOX_FIELD_ASSIGN(std_enc_params, GF_AdobeStdEncryptionParamsBox)
		break;
	}
	return GF_OK;
}

GF_Err ahdr_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err ahdr_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_full_box_write(s, bs);
}

GF_Err ahdr_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_AdobeDRMHeaderBox *ptr = (GF_AdobeDRMHeaderBox *)s;
	gf_isom_check_position(s, (GF_Box *)ptr->std_enc_params, &pos);
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE

GF_Box *aprm_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_AdobeStdEncryptionParamsBox, GF_ISOM_BOX_TYPE_APRM);
	tmp->version = 1;
	tmp->flags = 0;
	return (GF_Box *)tmp;
}

void aprm_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err aprm_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_AEIB:
		BOX_FIELD_ASSIGN(enc_info, GF_AdobeEncryptionInfoBox)
		break;
	case GF_ISOM_BOX_TYPE_AKEY:
		BOX_FIELD_ASSIGN(key_info, GF_AdobeKeyInfoBox)
		break;
	}
	return GF_OK;
}

GF_Err aprm_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err aprm_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_full_box_write(s, bs);
}

GF_Err aprm_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_AdobeStdEncryptionParamsBox *ptr = (GF_AdobeStdEncryptionParamsBox *)s;
	gf_isom_check_position(s, (GF_Box *)ptr->enc_info, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->key_info, &pos);
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE

GF_Box *aeib_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_AdobeEncryptionInfoBox, GF_ISOM_BOX_TYPE_AEIB);
	tmp->version = 1;
	tmp->flags = 0;
	return (GF_Box *)tmp;
}

void aeib_box_del(GF_Box *s)
{
	GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s;
	if (!ptr) return;
	if (ptr->enc_algo) gf_free(ptr->enc_algo);
	gf_free(ptr);
}

GF_Err aeib_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s;
	u32 len;

	if (!ptr->size) {
		//will force error exit
		ISOM_DECREASE_SIZE(ptr, 1);
	}

	len = (u32) ptr->size - 1;
	if (len) {
		ptr->enc_algo = (char *)gf_malloc(len*sizeof(char));
		if (!ptr->enc_algo) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->enc_algo, len);
		ptr->enc_algo[len-1] = 0;
	}
	ptr->key_length = gf_bs_read_u8(bs);
	ptr->size = 0;
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err aeib_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;
	if (ptr->enc_algo) {
		gf_bs_write_data(bs, (char *) ptr->enc_algo, (u32) strlen(ptr->enc_algo));
		gf_bs_write_u8(bs, 0); //string end
	}
	gf_bs_write_u8(bs, ptr->key_length);
	return GF_OK;
}

GF_Err aeib_box_size(GF_Box *s)
{
	GF_AdobeEncryptionInfoBox *ptr = (GF_AdobeEncryptionInfoBox*)s;
	if (ptr->enc_algo)
		ptr->size += strlen(ptr->enc_algo) + 1;
	ptr->size += 1; //KeyLength
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE

GF_Box *akey_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_AdobeKeyInfoBox, GF_ISOM_BOX_TYPE_AKEY);
	tmp->version = 1;
	tmp->flags = 0;
	return (GF_Box *)tmp;
}

void akey_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err akey_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
{
	GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s;
	switch (a->type) {
	case GF_ISOM_BOX_TYPE_FLXS:
		BOX_FIELD_ASSIGN(params, GF_AdobeFlashAccessParamsBox)
		break;
	}
	return GF_OK;
}

GF_Err akey_box_read(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_box_array_read(s, bs);
}

#ifndef GPAC_DISABLE_ISOM_WRITE
GF_Err akey_box_write(GF_Box *s, GF_BitStream *bs)
{
	return gf_isom_full_box_write(s, bs);
}

GF_Err akey_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_AdobeKeyInfoBox *ptr = (GF_AdobeKeyInfoBox *)s;
	gf_isom_check_position(s, (GF_Box *)ptr->params, &pos);
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE

GF_Box *flxs_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_AdobeFlashAccessParamsBox, GF_ISOM_BOX_TYPE_FLXS);
	return (GF_Box *)tmp;
}

void flxs_box_del(GF_Box *s)
{
	GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s;
	if (!ptr) return;
	if (ptr->metadata)
		gf_free(ptr->metadata);
	gf_free(ptr);
}

GF_Err flxs_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s;
	u32 len;

	len = (u32) ptr->size;
	if (len) {
		ptr->metadata = (char *)gf_malloc(len*sizeof(char));
		if (!ptr->metadata) return GF_OUT_OF_MEM;
		gf_bs_read_data(bs, ptr->metadata, len);
		ptr->metadata[len-1] = 0;
	}
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err flxs_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_box_write_header(s, bs);
	if (e) return e;
	if (ptr->metadata) {
		gf_bs_write_data(bs, ptr->metadata, (u32) strlen(ptr->metadata));
		gf_bs_write_u8(bs, 0); //string end
	}
	return GF_OK;
}

GF_Err flxs_box_size(GF_Box *s)
{
	GF_AdobeFlashAccessParamsBox *ptr = (GF_AdobeFlashAccessParamsBox*)s;
	if (ptr->metadata)
		ptr->size += strlen(ptr->metadata) + 1;
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE

GF_Box *adaf_box_new()
{
	ISOM_DECL_BOX_ALLOC(GF_AdobeDRMAUFormatBox, GF_ISOM_BOX_TYPE_ADAF);
	return (GF_Box *)tmp;
}

void adaf_box_del(GF_Box *s)
{
	gf_free(s);
}

GF_Err adaf_box_read(GF_Box *s, GF_BitStream *bs)
{
	GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox*)s;

	ISOM_DECREASE_SIZE(ptr, 3);
	ptr->selective_enc = gf_bs_read_u8(bs);
	gf_bs_read_u8(bs);//resersed
	ptr->IV_length = gf_bs_read_u8(bs);
	return GF_OK;
}

#ifndef GPAC_DISABLE_ISOM_WRITE

GF_Err adaf_box_write(GF_Box *s, GF_BitStream *bs)
{
	GF_Err e;
	GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox *) s;
	if (!s) return GF_BAD_PARAM;
	e = gf_isom_full_box_write(s, bs);
	if (e) return e;

	gf_bs_write_u8(bs, ptr->selective_enc);
	gf_bs_write_u8(bs, 0x0);
	gf_bs_write_u8(bs, ptr->IV_length);
	return GF_OK;
}

GF_Err adaf_box_size(GF_Box *s)
{
	GF_AdobeDRMAUFormatBox *ptr = (GF_AdobeDRMAUFormatBox*)s;
	ptr->size += 3;
	return GF_OK;
}
#endif //GPAC_DISABLE_ISOM_WRITE


#endif /*GPAC_DISABLE_ISOM*/
