LCOV - code coverage report
Current view: top level - odf - odf_code.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 848 1000 84.8 %
Date: 2021-04-29 23:48:07 Functions: 79 80 98.8 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2019
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / MPEG-4 ObjectDescriptor 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/odf_dev.h>
      27             : #include <gpac/utf.h>
      28             : 
      29             : #define DATE_CODING_LEN 5
      30             : 
      31             : #ifndef GPAC_MINIMAL_ODF
      32             : 
      33             : static GFINLINE GF_Err OD_ReadUTF8String(GF_BitStream *bs, char **string, Bool isUTF8, u32 *read)
      34             : {
      35             :         u32 len;
      36             :         *read = 1;
      37             :         len = gf_bs_read_int(bs, 8) + 1;
      38             :         if (gf_bs_available(bs) < len) return GF_BAD_PARAM;
      39             :         if (!isUTF8) len *= 2;
      40             :         (*string) = (char *) gf_malloc(sizeof(char)*len);
      41             :         if (! (*string) ) return GF_OUT_OF_MEM;
      42             :         gf_bs_read_data(bs, (*string), len);
      43             :         *read += len;
      44             :         return GF_OK;
      45             : }
      46             : 
      47             : static GFINLINE u32 OD_SizeUTF8String(char *string, Bool isUTF8)
      48             : {
      49             :         if (isUTF8) return 1 + (u32) strlen(string);
      50             :         return 1 + 2 * (u32) gf_utf8_wcslen((const unsigned short *)string);
      51             : }
      52             : 
      53             : static GFINLINE void OD_WriteUTF8String(GF_BitStream *bs, char *string, Bool isUTF8)
      54             : {
      55             :         u32 len;
      56             :         if (isUTF8) {
      57             :                 len = (u32) strlen(string);
      58             :                 gf_bs_write_int(bs, len, 8);
      59             :                 gf_bs_write_data(bs, string, len);
      60             :         } else {
      61             :                 len = (u32) gf_utf8_wcslen((const unsigned short *)string);
      62             :                 gf_bs_write_int(bs, len, 8);
      63             :                 gf_bs_write_data(bs, string, len*2);
      64             :         }
      65             : }
      66             : 
      67             : #endif // GPAC_MINIMAL_ODF
      68             : 
      69             : /*use to parse strings read the length as well - Warning : the alloc is done here !!*/
      70           7 : GF_Err gf_odf_read_url_string(GF_BitStream *bs, char **string, u32 *readBytes)
      71             : {
      72             :         u32 length;
      73           7 :         *readBytes = 0;
      74             : 
      75             :         /*if the string is not NULL, return an error...*/
      76           7 :         if (*string != NULL) return GF_BAD_PARAM;
      77             : 
      78             :         /*the len is always on 8 bits*/
      79           7 :         length = gf_bs_read_int(bs, 8);
      80           7 :         *readBytes = 1;
      81             :         /*JLF AMD to MPEG-4 systems :) - This is not conformant at all, just hoping MPEG will accept it soon
      82             :         since 255bytes URL is a real pain in the neck*/
      83           7 :         if (!length) {
      84           0 :                 length = gf_bs_read_int(bs, 32);
      85           0 :                 *readBytes += 4;
      86           0 :                 if (length>0xFFFF) return GF_ODF_INVALID_DESCRIPTOR;
      87             :         }
      88             :         /*we want to use strlen to get rid of "stringLength" => we need an extra 0*/
      89           7 :         (*string) = (char *) gf_malloc(length + 1);
      90           7 :         if (! *string) return GF_OUT_OF_MEM;
      91           7 :         gf_bs_read_data(bs, (*string), length);
      92           7 :         *readBytes += length;
      93           7 :         (*string)[length] = 0;
      94           7 :         return GF_OK;
      95             : }
      96             : 
      97             : /*writes string*/
      98          10 : GF_Err gf_odf_write_url_string(GF_BitStream *bs, char *string)
      99             : {
     100             :         u32 len;
     101             :         /*we accept NULL strings now*/
     102          10 :         if (!string) {
     103           0 :                 gf_bs_write_int(bs, 0, 8);
     104           0 :                 return GF_OK;
     105             :         }
     106          10 :         len = (u32) strlen(string);
     107          10 :         if (len > 255) {
     108           0 :                 gf_bs_write_int(bs, 0, 8);
     109           0 :                 gf_bs_write_int(bs, len, 32);
     110             :         } else {
     111          10 :                 gf_bs_write_int(bs, len, 8);
     112             :         }
     113          10 :         gf_bs_write_data(bs, string, len);
     114          10 :         return GF_OK;
     115             : }
     116             : 
     117           0 : u32 gf_odf_size_url_string(char *string)
     118             : {
     119          18 :         u32 len = (u32) strlen(string);
     120          18 :         if (len>255) return len+5;
     121          18 :         return len+1;
     122             : }
     123             : 
     124        8059 : GF_Descriptor *gf_odf_new_esd()
     125             : {
     126        8059 :         GF_ESD *newDesc = (GF_ESD *) gf_malloc(sizeof(GF_ESD));
     127        8059 :         if (!newDesc) return NULL;
     128             :         memset(newDesc, 0, sizeof(GF_ESD));
     129        8059 :         newDesc->IPIDataSet = gf_list_new();
     130        8059 :         newDesc->IPMPDescriptorPointers = gf_list_new();
     131        8059 :         newDesc->extensionDescriptors = gf_list_new();
     132        8059 :         newDesc->tag = GF_ODF_ESD_TAG;
     133        8059 :         return (GF_Descriptor *) newDesc;
     134             : }
     135             : 
     136             : 
     137        8059 : GF_Err gf_odf_del_esd(GF_ESD *esd)
     138             : {
     139             :         GF_Err e;
     140        8059 :         if (!esd) return GF_BAD_PARAM;
     141        8059 :         if (esd->URLString)  gf_free(esd->URLString);
     142             : 
     143        8059 :         if (esd->decoderConfig)      {
     144        7858 :                 e = gf_odf_delete_descriptor((GF_Descriptor *) esd->decoderConfig);
     145        7858 :                 if (e) return e;
     146             :         }
     147        8059 :         if (esd->slConfig) {
     148        7406 :                 e = gf_odf_delete_descriptor((GF_Descriptor *) esd->slConfig);
     149        7406 :                 if (e) return e;
     150             :         }
     151        8059 :         if (esd->ipiPtr) {
     152           0 :                 e = gf_odf_delete_descriptor((GF_Descriptor *) esd->ipiPtr);
     153           0 :                 if (e) return e;
     154             :         }
     155        8059 :         if (esd->qos) {
     156           0 :                 e = gf_odf_delete_descriptor((GF_Descriptor *) esd->qos);
     157           0 :                 if (e) return e;
     158             :         }
     159        8059 :         if (esd->RegDescriptor)      {
     160           0 :                 e = gf_odf_delete_descriptor((GF_Descriptor *) esd->RegDescriptor);
     161           0 :                 if (e) return e;
     162             :         }
     163        8059 :         if (esd->langDesc)   {
     164          30 :                 e = gf_odf_delete_descriptor((GF_Descriptor *) esd->langDesc);
     165          30 :                 if (e) return e;
     166             :         }
     167             : 
     168        8059 :         e = gf_odf_delete_descriptor_list(esd->IPIDataSet);
     169        8059 :         if (e) return e;
     170        8059 :         e = gf_odf_delete_descriptor_list(esd->IPMPDescriptorPointers);
     171        8059 :         if (e) return e;
     172        8059 :         e = gf_odf_delete_descriptor_list(esd->extensionDescriptors);
     173        8059 :         if (e) return e;
     174        8059 :         gf_free(esd);
     175        8059 :         return GF_OK;
     176             : }
     177             : 
     178             : 
     179        8294 : GF_Err AddDescriptorToESD(GF_ESD *esd, GF_Descriptor *desc)
     180             : {
     181        8294 :         if (!esd || !desc) return GF_BAD_PARAM;
     182             : 
     183        8294 :         switch (desc->tag) {
     184        4311 :         case GF_ODF_DCD_TAG:
     185        4311 :                 if (esd->decoderConfig) return GF_ODF_INVALID_DESCRIPTOR;
     186        4311 :                 esd->decoderConfig = (GF_DecoderConfig *) desc;
     187        4311 :                 break;
     188             : 
     189        3786 :         case GF_ODF_SLC_TAG:
     190        3786 :                 if (esd->slConfig) return GF_ODF_INVALID_DESCRIPTOR;
     191        3786 :                 esd->slConfig = (GF_SLConfig *) desc;
     192        3786 :                 break;
     193             : 
     194         168 :         case GF_ODF_MUXINFO_TAG:
     195         168 :                 gf_list_add(esd->extensionDescriptors, desc);
     196         168 :                 break;
     197             : 
     198           9 :         case GF_ODF_LANG_TAG:
     199           9 :                 if (esd->langDesc) return GF_ODF_INVALID_DESCRIPTOR;
     200           9 :                 esd->langDesc = (GF_Language *) desc;
     201           9 :                 break;
     202             : 
     203             : #ifndef GPAC_MINIMAL_ODF
     204             :         //the GF_ODF_ISOM_IPI_PTR_TAG is only used in the file format and replaces GF_ODF_IPI_PTR_TAG...
     205             :         case GF_ODF_ISOM_IPI_PTR_TAG:
     206             :         case GF_ODF_IPI_PTR_TAG:
     207             :                 if (esd->ipiPtr) return GF_ODF_INVALID_DESCRIPTOR;
     208             :                 esd->ipiPtr = (GF_IPIPtr *) desc;
     209             :                 break;
     210             : 
     211             :         case GF_ODF_QOS_TAG:
     212             :                 if (esd->qos) return GF_ODF_INVALID_DESCRIPTOR;
     213             :                 esd->qos  =(GF_QoS_Descriptor *) desc;
     214             :                 break;
     215             : 
     216             :         case GF_ODF_CI_TAG:
     217             :         case GF_ODF_SCI_TAG:
     218             :                 return gf_list_add(esd->IPIDataSet, desc);
     219             : 
     220             :         //we use the same struct for v1 and v2 IPMP DPs
     221             :         case GF_ODF_IPMP_PTR_TAG:
     222             :                 return gf_list_add(esd->IPMPDescriptorPointers, desc);
     223             : 
     224             :         case GF_ODF_REG_TAG:
     225             :                 if (esd->RegDescriptor) return GF_ODF_INVALID_DESCRIPTOR;
     226             :                 esd->RegDescriptor =(GF_Registration *) desc;
     227             :                 break;
     228             : #endif
     229             : 
     230          20 :         default:
     231          20 :                 if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
     232             :                         (desc->tag <= GF_ODF_EXT_END_TAG) ) {
     233          20 :                         return gf_list_add(esd->extensionDescriptors, desc);
     234             :                 }
     235           0 :                 gf_odf_delete_descriptor(desc);
     236           0 :                 return GF_OK;
     237             :         }
     238             : 
     239             :         return GF_OK;
     240             : }
     241             : 
     242        3754 : GF_Err gf_odf_read_esd(GF_BitStream *bs, GF_ESD *esd, u32 DescSize)
     243             : {
     244             :         GF_Err e = GF_OK;
     245             :         u32 ocrflag, urlflag, streamdependflag, tmp_size, nbBytes, read;
     246             : 
     247        3754 :         if (! esd) return GF_BAD_PARAM;
     248             : 
     249             :         nbBytes = 0;
     250             : 
     251        3754 :         esd->ESID = gf_bs_read_int(bs, 16);
     252        3754 :         streamdependflag = gf_bs_read_int(bs, 1);
     253        3754 :         urlflag = gf_bs_read_int(bs, 1);
     254        3754 :         ocrflag = gf_bs_read_int(bs, 1);
     255        3754 :         esd->streamPriority = gf_bs_read_int(bs, 5);
     256             :         nbBytes += 3;
     257             : 
     258        3754 :         if (streamdependflag) {
     259          59 :                 esd->dependsOnESID = gf_bs_read_int(bs, 16);
     260             :                 nbBytes += 2;
     261             :         }
     262             : 
     263        3754 :         if (urlflag) {
     264           0 :                 e = gf_odf_read_url_string(bs, & esd->URLString, &read);
     265           0 :                 if (e) return e;
     266           0 :                 nbBytes += read;
     267             :         }
     268        3754 :         if (ocrflag) {
     269         221 :                 esd->OCRESID = gf_bs_read_int(bs, 16);
     270         221 :                 nbBytes += 2;
     271             :         }
     272             : 
     273       11268 :         while (nbBytes < DescSize) {
     274        7514 :                 GF_Descriptor *tmp = NULL;
     275        7514 :                 e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
     276             :                 /*fix for iPod files*/
     277        7514 :                 if (e==GF_ODF_INVALID_DESCRIPTOR) {
     278           0 :                         nbBytes += tmp_size;
     279           0 :                         if (nbBytes>DescSize) return e;
     280           0 :                         gf_bs_read_int(bs, DescSize-nbBytes);
     281           0 :                         return GF_OK;
     282             :                 }
     283        7514 :                 if (e) return e;
     284        7514 :                 if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
     285        7514 :                 e = AddDescriptorToESD(esd, tmp);
     286        7514 :                 if (e) {
     287           0 :                         gf_odf_desc_del(tmp);
     288           0 :                         return e;
     289             :                 }
     290        7514 :                 nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
     291             : 
     292             :                 //apple fix
     293        7514 :                 if (!tmp_size) nbBytes = DescSize;
     294             : 
     295             :         }
     296        3754 :         if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
     297        3754 :         return e;
     298             : 
     299             : }
     300             : 
     301        6121 : GF_Err gf_odf_size_esd(GF_ESD *esd, u32 *outSize)
     302             : {
     303             :         GF_Err e;
     304             :         u32 tmpSize;
     305        6121 :         if (! esd) return GF_BAD_PARAM;
     306             : 
     307             :         *outSize = 0;
     308        6121 :         *outSize += 3;
     309             : 
     310        6121 :         if (esd->dependsOnESID) *outSize += 2;
     311        6129 :         if (esd->URLString) *outSize += gf_odf_size_url_string(esd->URLString);
     312        6121 :         if (esd->OCRESID) *outSize += 2;
     313             : 
     314        6121 :         if (esd->decoderConfig) {
     315        6116 :                 e = gf_odf_size_descriptor((GF_Descriptor *) esd->decoderConfig, &tmpSize);
     316        6116 :                 if (e) return e;
     317        6116 :                 *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
     318             :         }
     319        6121 :         if (esd->slConfig) {
     320        6116 :                 e = gf_odf_size_descriptor((GF_Descriptor *) esd->slConfig, &tmpSize);
     321        6116 :                 if (e) return e;
     322        6116 :                 *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
     323             :         }
     324        6121 :         if (esd->ipiPtr) {
     325           0 :                 e = gf_odf_size_descriptor((GF_Descriptor *) esd->ipiPtr, &tmpSize);
     326           0 :                 if (e) return e;
     327           0 :                 *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
     328             :         }
     329        6121 :         if (esd->langDesc) {
     330           7 :                 e = gf_odf_size_descriptor((GF_Descriptor *) esd->langDesc, &tmpSize);
     331           7 :                 if (e) return e;
     332           7 :                 *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
     333             :         }
     334             : 
     335        6121 :         e = gf_odf_size_descriptor_list(esd->IPIDataSet, outSize);
     336        6121 :         if (e) return e;
     337        6121 :         e = gf_odf_size_descriptor_list(esd->IPMPDescriptorPointers, outSize);
     338        6121 :         if (e) return e;
     339        6121 :         if (esd->qos) {
     340           0 :                 e = gf_odf_size_descriptor((GF_Descriptor *) esd->qos, &tmpSize);
     341           0 :                 if (e) return e;
     342           0 :                 *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
     343             :         }
     344        6121 :         if (esd->RegDescriptor) {
     345           0 :                 e = gf_odf_size_descriptor((GF_Descriptor *) esd->RegDescriptor, &tmpSize);
     346           0 :                 if (e) return e;
     347           0 :                 *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
     348             :         }
     349        6121 :         return gf_odf_size_descriptor_list(esd->extensionDescriptors, outSize);
     350             : }
     351             : 
     352        3639 : GF_Err gf_odf_write_esd(GF_BitStream *bs, GF_ESD *esd)
     353             : {
     354             :         GF_Err e;
     355             :         u32 size;
     356        3639 :         if (! esd) return GF_BAD_PARAM;
     357             : 
     358        3639 :         e = gf_odf_size_descriptor((GF_Descriptor *)esd, &size);
     359        3639 :         if (e) return e;
     360        3639 :         e = gf_odf_write_base_descriptor(bs, esd->tag, size);
     361        3639 :         if (e) return e;
     362             : 
     363        3639 :         gf_bs_write_int(bs, esd->ESID, 16);
     364        3639 :         gf_bs_write_int(bs, esd->dependsOnESID ? 1 : 0, 1);
     365        3639 :         gf_bs_write_int(bs, esd->URLString != NULL ? 1 : 0, 1);
     366        3639 :         gf_bs_write_int(bs, esd->OCRESID ? 1 : 0, 1);
     367        3639 :         gf_bs_write_int(bs, esd->streamPriority, 5);
     368             : 
     369        3639 :         if (esd->dependsOnESID) {
     370          59 :                 gf_bs_write_int(bs, esd->dependsOnESID, 16);
     371             :         }
     372        3639 :         if (esd->URLString) {
     373           4 :                 e = gf_odf_write_url_string(bs, esd->URLString);
     374           4 :                 if (e) return e;
     375             :         }
     376             : 
     377             : 
     378        3639 :         if (esd->OCRESID) {
     379         240 :                 gf_bs_write_int(bs, esd->OCRESID, 16);
     380             :         }
     381        3639 :         if (esd->decoderConfig) {
     382        3637 :                 e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->decoderConfig);
     383        3637 :                 if (e) return e;
     384             :         }
     385        3639 :         if (esd->slConfig) {
     386        3637 :                 e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->slConfig);
     387        3637 :                 if (e) return e;
     388             :         }
     389        3639 :         if (esd->ipiPtr) {
     390           0 :                 e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->ipiPtr);
     391           0 :                 if (e) return e;
     392             :         }
     393        3639 :         if (esd->langDesc) {
     394           4 :                 e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->langDesc);
     395           4 :                 if (e) return e;
     396             :         }
     397             : 
     398        3639 :         e = gf_odf_write_descriptor_list(bs, esd->IPIDataSet);
     399        3639 :         if (e) return e;
     400        3639 :         e = gf_odf_write_descriptor_list(bs, esd->IPMPDescriptorPointers);
     401        3639 :         if (e) return e;
     402        3639 :         if (esd->qos) {
     403           0 :                 e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->qos);
     404           0 :                 if (e) return e;
     405             :         }
     406        3639 :         if (esd->RegDescriptor) {
     407           0 :                 e = gf_odf_write_descriptor(bs, (GF_Descriptor *) esd->RegDescriptor);
     408           0 :                 if (e) return e;
     409             :         }
     410        3639 :         return gf_odf_write_descriptor_list(bs, esd->extensionDescriptors);
     411             : }
     412             : 
     413         390 : GF_Descriptor *gf_odf_new_iod()
     414             : {
     415         390 :         GF_InitialObjectDescriptor *newDesc = (GF_InitialObjectDescriptor *) gf_malloc(sizeof(GF_InitialObjectDescriptor));
     416         390 :         if (!newDesc) return NULL;
     417             :         memset(newDesc, 0, sizeof(GF_InitialObjectDescriptor));
     418             : 
     419         390 :         newDesc->ESDescriptors = gf_list_new();
     420         390 :         newDesc->OCIDescriptors = gf_list_new();
     421         390 :         newDesc->IPMP_Descriptors = gf_list_new();
     422             : 
     423         390 :         newDesc->extensionDescriptors = gf_list_new();
     424         390 :         newDesc->tag = GF_ODF_IOD_TAG;
     425         390 :         return (GF_Descriptor *) newDesc;
     426             : }
     427             : 
     428         963 : GF_Err gf_odf_del_iod(GF_InitialObjectDescriptor *iod)
     429             : {
     430             :         GF_Err e;
     431         963 :         if (!iod) return GF_BAD_PARAM;
     432         963 :         if (iod->URLString)  gf_free(iod->URLString);
     433         963 :         e = gf_odf_delete_descriptor_list(iod->ESDescriptors);
     434         963 :         if (e) return e;
     435         963 :         e = gf_odf_delete_descriptor_list(iod->OCIDescriptors);
     436         963 :         if (e) return e;
     437         963 :         e = gf_odf_delete_descriptor_list(iod->IPMP_Descriptors);
     438         963 :         if (e) return e;
     439         963 :         e = gf_odf_delete_descriptor_list(iod->extensionDescriptors);
     440         963 :         if (e) return e;
     441         963 :         if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *) iod->IPMPToolList);
     442         963 :         gf_free(iod);
     443         963 :         return GF_OK;
     444             : }
     445             : 
     446         528 : GF_Err AddDescriptorToIOD(GF_InitialObjectDescriptor *iod, GF_Descriptor *desc)
     447             : {
     448         528 :         if (!iod || !desc) return GF_BAD_PARAM;
     449             : 
     450         528 :         switch (desc->tag) {
     451         522 :         case GF_ODF_ESD_TAG:
     452         522 :                 return gf_list_add(iod->ESDescriptors, desc);
     453             : 
     454             :         //we use the same struct for v1 and v2 IPMP DPs
     455           0 :         case GF_ODF_IPMP_PTR_TAG:
     456             :         /*IPMPX*/
     457             :         case GF_ODF_IPMP_TAG:
     458           0 :                 return gf_list_add(iod->IPMP_Descriptors, desc);
     459             : 
     460             :         /*IPMPX*/
     461           0 :         case GF_ODF_IPMP_TL_TAG:
     462           0 :                 if (iod->IPMPToolList) gf_odf_desc_del((GF_Descriptor *)iod->IPMPToolList);
     463           0 :                 iod->IPMPToolList = (GF_IPMP_ToolList *)desc;
     464           0 :                 return GF_OK;
     465             : 
     466             :         default:
     467             :                 break;
     468             :         }
     469           6 :         if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) && (desc->tag <= GF_ODF_OCI_END_TAG) ) return gf_list_add(iod->OCIDescriptors, desc);
     470           0 :         if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) && (desc->tag <= GF_ODF_EXT_END_TAG) ) return gf_list_add(iod->extensionDescriptors, desc);
     471             :         return GF_BAD_PARAM;
     472             : }
     473             : 
     474           4 : GF_Err gf_odf_read_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod, u32 DescSize)
     475             : {
     476             :         GF_Err e;
     477             :         u32 urlflag, read;
     478             :         u32 tmp_size, nbBytes = 0;
     479           4 :         if (! iod) return GF_BAD_PARAM;
     480             : 
     481           4 :         iod->objectDescriptorID = gf_bs_read_int(bs, 10);
     482           4 :         urlflag = gf_bs_read_int(bs, 1);
     483           4 :         iod->inlineProfileFlag = gf_bs_read_int(bs, 1);
     484           4 :         /*reserved = */gf_bs_read_int(bs, 4);
     485             :         nbBytes += 2;
     486             : 
     487           4 :         if (urlflag) {
     488           0 :                 e = gf_odf_read_url_string(bs, & iod->URLString, &read);
     489           0 :                 if (e) return e;
     490           0 :                 nbBytes += read;
     491             :         } else {
     492           4 :                 iod->OD_profileAndLevel = gf_bs_read_int(bs, 8);
     493           4 :                 iod->scene_profileAndLevel = gf_bs_read_int(bs, 8);
     494           4 :                 iod->audio_profileAndLevel = gf_bs_read_int(bs, 8);
     495           4 :                 iod->visual_profileAndLevel = gf_bs_read_int(bs, 8);
     496           4 :                 iod->graphics_profileAndLevel = gf_bs_read_int(bs, 8);
     497             :                 nbBytes += 5;
     498             :         }
     499             : 
     500          11 :         while (nbBytes < DescSize) {
     501           7 :                 GF_Descriptor *tmp = NULL;
     502           7 :                 e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
     503           7 :                 if (e) return e;
     504           7 :                 if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
     505           7 :                 e = AddDescriptorToIOD(iod, tmp);
     506           7 :                 if (e) {
     507           0 :                         gf_odf_delete_descriptor(tmp);
     508           0 :                         return e;
     509             :                 }
     510           7 :                 nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
     511             :         }
     512           4 :         if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
     513           4 :         return GF_OK;
     514             : }
     515             : 
     516          83 : GF_Err gf_odf_size_iod(GF_InitialObjectDescriptor *iod, u32 *outSize)
     517             : {
     518             :         GF_Err e;
     519          83 :         if (! iod) return GF_BAD_PARAM;
     520             : 
     521             :         *outSize = 0;
     522          83 :         *outSize += 2;
     523          83 :         if (iod->URLString) {
     524           0 :                 *outSize += gf_odf_size_url_string(iod->URLString);
     525             :         } else {
     526          83 :                 *outSize += 5;
     527          83 :                 e = gf_odf_size_descriptor_list(iod->ESDescriptors, outSize);
     528          83 :                 if (e) return e;
     529          83 :                 e = gf_odf_size_descriptor_list(iod->OCIDescriptors, outSize);
     530          83 :                 if (e) return e;
     531          83 :                 e = gf_odf_size_descriptor_list(iod->IPMP_Descriptors, outSize);
     532          83 :                 if (e) return e;
     533             : 
     534             :         }
     535          83 :         e = gf_odf_size_descriptor_list(iod->extensionDescriptors, outSize);
     536          83 :         if (e) return e;
     537          83 :         if (iod->IPMPToolList) {
     538             :                 u32 tmpSize;
     539           0 :                 e = gf_odf_size_descriptor((GF_Descriptor *) iod->IPMPToolList, &tmpSize);
     540           0 :                 if (e) return e;
     541           0 :                 *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
     542             :         }
     543             :         return GF_OK;
     544             : }
     545             : 
     546           9 : GF_Err gf_odf_write_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod)
     547             : {
     548             :         GF_Err e;
     549             :         u32 size;
     550           9 :         if (! iod) return GF_BAD_PARAM;
     551             : 
     552           9 :         e = gf_odf_size_descriptor((GF_Descriptor *)iod, &size);
     553           9 :         if (e) return e;
     554           9 :         e = gf_odf_write_base_descriptor(bs, iod->tag, size);
     555           9 :         if (e) return e;
     556             : 
     557           9 :         gf_bs_write_int(bs, iod->objectDescriptorID, 10);
     558           9 :         gf_bs_write_int(bs, iod->URLString != NULL ? 1 : 0, 1);
     559           9 :         gf_bs_write_int(bs, iod->inlineProfileFlag, 1);
     560           9 :         gf_bs_write_int(bs, 15, 4);             //reserved: 0b1111 == 15
     561             : 
     562           9 :         if (iod->URLString) {
     563           0 :                 gf_odf_write_url_string(bs, iod->URLString);
     564             :         } else {
     565           9 :                 gf_bs_write_int(bs, iod->OD_profileAndLevel, 8);
     566           9 :                 gf_bs_write_int(bs, iod->scene_profileAndLevel, 8);
     567           9 :                 gf_bs_write_int(bs, iod->audio_profileAndLevel, 8);
     568           9 :                 gf_bs_write_int(bs, iod->visual_profileAndLevel, 8);
     569           9 :                 gf_bs_write_int(bs, iod->graphics_profileAndLevel, 8);
     570           9 :                 e = gf_odf_write_descriptor_list(bs, iod->ESDescriptors);
     571           9 :                 if (e) return e;
     572           9 :                 e = gf_odf_write_descriptor_list(bs, iod->OCIDescriptors);
     573           9 :                 if (e) return e;
     574           9 :                 e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
     575           9 :                 if (e) return e;
     576           9 :                 e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_TAG);
     577           9 :                 if (e) return e;
     578           9 :                 if (iod->IPMPToolList) {
     579           0 :                         e = gf_odf_write_descriptor(bs, (GF_Descriptor *) iod->IPMPToolList);
     580           0 :                         if (e) return e;
     581             :                 }
     582             :         }
     583           9 :         return gf_odf_write_descriptor_list(bs, iod->extensionDescriptors);
     584             : }
     585             : 
     586             : 
     587             : 
     588         701 : GF_Descriptor *gf_odf_new_od()
     589             : {
     590             :         GF_ObjectDescriptor *newDesc;
     591         701 :         GF_SAFEALLOC(newDesc, GF_ObjectDescriptor);
     592         701 :         if (!newDesc) return NULL;
     593             : 
     594         701 :         newDesc->URLString = NULL;
     595         701 :         newDesc->ESDescriptors = gf_list_new();
     596         701 :         newDesc->OCIDescriptors = gf_list_new();
     597         701 :         newDesc->IPMP_Descriptors = gf_list_new();
     598         701 :         newDesc->extensionDescriptors = gf_list_new();
     599         701 :         newDesc->objectDescriptorID = 0;
     600         701 :         newDesc->tag = GF_ODF_OD_TAG;
     601         701 :         return (GF_Descriptor *) newDesc;
     602             : }
     603             : 
     604         797 : GF_Err gf_odf_del_od(GF_ObjectDescriptor *od)
     605             : {
     606             :         GF_Err e;
     607         797 :         if (!od) return GF_BAD_PARAM;
     608         797 :         if (od->URLString)   gf_free(od->URLString);
     609         797 :         e = gf_odf_delete_descriptor_list(od->ESDescriptors);
     610         797 :         if (e) return e;
     611         797 :         e = gf_odf_delete_descriptor_list(od->OCIDescriptors);
     612         797 :         if (e) return e;
     613         797 :         e = gf_odf_delete_descriptor_list(od->IPMP_Descriptors);
     614         797 :         if (e) return e;
     615         797 :         e = gf_odf_delete_descriptor_list(od->extensionDescriptors);
     616         797 :         if (e) return e;
     617         797 :         gf_free(od);
     618         797 :         return GF_OK;
     619             : }
     620             : 
     621         628 : GF_Err AddDescriptorToOD(GF_ObjectDescriptor *od, GF_Descriptor *desc)
     622             : {
     623         628 :         if (!od || !desc) return GF_BAD_PARAM;
     624             : 
     625             :         //check if we can handle ContentClassif tags
     626         628 :         if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) &&
     627             :                 (desc->tag <= GF_ODF_OCI_END_TAG) ) {
     628           9 :                 return gf_list_add(od->OCIDescriptors, desc);
     629             :         }
     630             : 
     631             :         //or extensions
     632         619 :         if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
     633             :                 (desc->tag <= GF_ODF_EXT_END_TAG) ) {
     634           0 :                 return gf_list_add(od->extensionDescriptors, desc);
     635             :         }
     636             : 
     637             :         //to cope with envivio
     638         619 :         switch (desc->tag) {
     639         619 :         case GF_ODF_ESD_TAG:
     640             :         case GF_ODF_ESD_REF_TAG:
     641         619 :                 return gf_list_add(od->ESDescriptors, desc);
     642             : 
     643             :         //we use the same struct for v1 and v2 IPMP DPs
     644           0 :         case GF_ODF_IPMP_PTR_TAG:
     645             :         case GF_ODF_IPMP_TAG:
     646           0 :                 return gf_list_add(od->IPMP_Descriptors, desc);
     647             : 
     648             :         default:
     649             :                 return GF_BAD_PARAM;
     650             :         }
     651             : }
     652             : 
     653         323 : GF_Err gf_odf_read_od(GF_BitStream *bs, GF_ObjectDescriptor *od, u32 DescSize)
     654             : {
     655             :         GF_Err e;
     656             :         u32 urlflag;
     657             :         u32 tmpSize, nbBytes = 0;
     658         323 :         if (! od) return GF_BAD_PARAM;
     659             : 
     660         323 :         od->objectDescriptorID = gf_bs_read_int(bs, 10);
     661         323 :         urlflag = gf_bs_read_int(bs, 1);
     662         323 :         /*reserved = */gf_bs_read_int(bs, 5);
     663             :         nbBytes += 2;
     664             : 
     665         323 :         if (urlflag) {
     666             :                 u32 read;
     667           4 :                 e = gf_odf_read_url_string(bs, & od->URLString, &read);
     668           4 :                 if (e) return e;
     669           4 :                 nbBytes += read;
     670             :         }
     671             : 
     672         636 :         while (nbBytes < DescSize) {
     673         313 :                 GF_Descriptor *tmp = NULL;
     674         313 :                 e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
     675         313 :                 if (e) return e;
     676         313 :                 if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
     677         313 :                 e = AddDescriptorToOD(od, tmp);
     678         313 :                 if (e) {
     679           0 :                         gf_odf_desc_del(tmp);
     680           0 :                         return e;
     681             :                 }
     682         313 :                 nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
     683             :         }
     684         323 :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
     685         323 :         return GF_OK;
     686             : }
     687             : 
     688         535 : GF_Err gf_odf_size_od(GF_ObjectDescriptor *od, u32 *outSize)
     689             : {
     690             :         GF_Err e;
     691         535 :         if (! od) return GF_BAD_PARAM;
     692             : 
     693         535 :         *outSize = 2;
     694         535 :         if (od->URLString) {
     695           6 :                 *outSize += gf_odf_size_url_string(od->URLString);
     696             :         } else {
     697         529 :                 e = gf_odf_size_descriptor_list(od->ESDescriptors, outSize);
     698         529 :                 if (e) return e;
     699         529 :                 e = gf_odf_size_descriptor_list(od->OCIDescriptors, outSize);
     700         529 :                 if (e) return e;
     701         529 :                 e = gf_odf_size_descriptor_list(od->IPMP_Descriptors, outSize);
     702         529 :                 if (e) return e;
     703             :         }
     704         535 :         return gf_odf_size_descriptor_list(od->extensionDescriptors, outSize);
     705             : }
     706             : 
     707         335 : GF_Err gf_odf_write_od(GF_BitStream *bs, GF_ObjectDescriptor *od)
     708             : {
     709             :         GF_Err e;
     710             :         u32 size;
     711         335 :         if (! od) return GF_BAD_PARAM;
     712             : 
     713         335 :         e = gf_odf_size_descriptor((GF_Descriptor *)od, &size);
     714         335 :         if (e) return e;
     715         335 :         e = gf_odf_write_base_descriptor(bs, od->tag, size);
     716         335 :         if (e) return e;
     717             : 
     718         335 :         gf_bs_write_int(bs, od->objectDescriptorID, 10);
     719         335 :         gf_bs_write_int(bs, od->URLString != NULL ? 1 : 0, 1);
     720         335 :         gf_bs_write_int(bs, 31, 5);             //reserved: 0b1111.1 == 31
     721             : 
     722         335 :         if (od->URLString) {
     723           4 :                 gf_odf_write_url_string(bs, od->URLString);
     724             :         } else {
     725         331 :                 e = gf_odf_write_descriptor_list(bs, od->ESDescriptors);
     726         331 :                 if (e) return e;
     727         331 :                 e = gf_odf_write_descriptor_list(bs, od->OCIDescriptors);
     728         331 :                 if (e) return e;
     729         331 :                 e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
     730         331 :                 if (e) return e;
     731         331 :                 e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_TAG);
     732         331 :                 if (e) return e;
     733             :         }
     734         335 :         return gf_odf_write_descriptor_list(bs, od->extensionDescriptors);
     735             : }
     736             : 
     737        1857 : GF_Descriptor *gf_odf_new_isom_iod()
     738             : {
     739        1857 :         GF_IsomInitialObjectDescriptor *newDesc = (GF_IsomInitialObjectDescriptor *) gf_malloc(sizeof(GF_IsomInitialObjectDescriptor));
     740        1857 :         if (!newDesc) return NULL;
     741             :         memset(newDesc, 0, sizeof(GF_IsomInitialObjectDescriptor));
     742             : 
     743        1857 :         newDesc->ES_ID_IncDescriptors = gf_list_new();
     744        1857 :         newDesc->ES_ID_RefDescriptors = gf_list_new();
     745        1857 :         newDesc->OCIDescriptors = gf_list_new();
     746        1857 :         newDesc->IPMP_Descriptors = gf_list_new();
     747        1857 :         newDesc->extensionDescriptors = gf_list_new();
     748        1857 :         newDesc->tag = GF_ODF_ISOM_IOD_TAG;
     749             : 
     750             :         //by default create an IOD with no inline and no capabilities
     751        1857 :         newDesc->audio_profileAndLevel = 0xFF;
     752        1857 :         newDesc->graphics_profileAndLevel = 0xFF;
     753        1857 :         newDesc->scene_profileAndLevel = 0xFF;
     754        1857 :         newDesc->OD_profileAndLevel = 0xFF;
     755        1857 :         newDesc->visual_profileAndLevel = 0xFF;
     756        1857 :         return (GF_Descriptor *) newDesc;
     757             : }
     758             : 
     759        1893 : GF_Err gf_odf_del_isom_iod(GF_IsomInitialObjectDescriptor *iod)
     760             : {
     761             :         GF_Err e;
     762        1893 :         if (!iod) return GF_BAD_PARAM;
     763        1893 :         if (iod->URLString)  gf_free(iod->URLString);
     764        1893 :         e = gf_odf_delete_descriptor_list(iod->ES_ID_IncDescriptors);
     765        1893 :         if (e) return e;
     766        1893 :         e = gf_odf_delete_descriptor_list(iod->ES_ID_RefDescriptors);
     767        1893 :         if (e) return e;
     768        1893 :         e = gf_odf_delete_descriptor_list(iod->OCIDescriptors);
     769        1893 :         if (e) return e;
     770        1893 :         e = gf_odf_delete_descriptor_list(iod->IPMP_Descriptors);
     771        1893 :         if (e) return e;
     772        1893 :         e = gf_odf_delete_descriptor_list(iod->extensionDescriptors);
     773        1893 :         if (e) return e;
     774        1893 :         if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *) iod->IPMPToolList);
     775        1893 :         gf_free(iod);
     776        1893 :         return GF_OK;
     777             : }
     778             : 
     779         279 : GF_Err AddDescriptorToIsomIOD(GF_IsomInitialObjectDescriptor *iod, GF_Descriptor *desc)
     780             : {
     781         279 :         if (!iod || !desc) return GF_BAD_PARAM;
     782             : 
     783         279 :         switch (desc->tag) {
     784             :         case GF_ODF_ESD_TAG:
     785             :                 return GF_ODF_FORBIDDEN_DESCRIPTOR;
     786             : 
     787         261 :         case GF_ODF_ESD_INC_TAG:
     788             :                 //there shouldn't be ref if inc
     789         261 :                 if (gf_list_count(iod->ES_ID_RefDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
     790         261 :                 return gf_list_add(iod->ES_ID_IncDescriptors, desc);
     791             : 
     792           0 :         case GF_ODF_ESD_REF_TAG:
     793             :                 //there shouldn't be inc if ref
     794           0 :                 if (gf_list_count(iod->ES_ID_IncDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
     795           0 :                 return gf_list_add(iod->ES_ID_RefDescriptors, desc);
     796             : 
     797             :         //we use the same struct for v1 and v2 IPMP DPs
     798           0 :         case GF_ODF_IPMP_PTR_TAG:
     799             :         case GF_ODF_IPMP_TAG:
     800           0 :                 return gf_list_add(iod->IPMP_Descriptors, desc);
     801             : 
     802             :         /*IPMPX*/
     803           0 :         case GF_ODF_IPMP_TL_TAG:
     804           0 :                 if (iod->IPMPToolList) gf_odf_desc_del((GF_Descriptor *)iod->IPMPToolList);
     805           0 :                 iod->IPMPToolList = (GF_IPMP_ToolList *)desc;
     806           0 :                 return GF_OK;
     807             : 
     808             :         default:
     809             :                 break;
     810             :         }
     811             :         //check if we can handle ContentClassif tags
     812          18 :         if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) && (desc->tag <= GF_ODF_OCI_END_TAG) ) return gf_list_add(iod->OCIDescriptors, desc);
     813             :         //or extensions
     814           0 :         if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) && (desc->tag <= GF_ODF_EXT_END_TAG) ) return gf_list_add(iod->extensionDescriptors, desc);
     815             :         return GF_BAD_PARAM;
     816             : }
     817             : 
     818        1383 : GF_Err gf_odf_read_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *iod, u32 DescSize)
     819             : {
     820             :         u32 nbBytes = 0, tmpSize;
     821             :         u32 urlflag;
     822             :         GF_Err e;
     823        1383 :         if (! iod) return GF_BAD_PARAM;
     824             : 
     825        1383 :         iod->objectDescriptorID = gf_bs_read_int(bs, 10);
     826        1383 :         urlflag = gf_bs_read_int(bs, 1);
     827        1383 :         iod->inlineProfileFlag = gf_bs_read_int(bs, 1);
     828        1383 :         /*reserved = */gf_bs_read_int(bs, 4);
     829             :         nbBytes += 2;
     830             : 
     831        1383 :         if (urlflag) {
     832             :                 u32 read;
     833           0 :                 e = gf_odf_read_url_string(bs, & iod->URLString, &read);
     834           0 :                 if (e) return e;
     835           0 :                 nbBytes += read;
     836             :         } else {
     837        1383 :                 iod->OD_profileAndLevel = gf_bs_read_int(bs, 8);
     838        1383 :                 iod->scene_profileAndLevel = gf_bs_read_int(bs, 8);
     839        1383 :                 iod->audio_profileAndLevel = gf_bs_read_int(bs, 8);
     840        1383 :                 iod->visual_profileAndLevel = gf_bs_read_int(bs, 8);
     841        1383 :                 iod->graphics_profileAndLevel = gf_bs_read_int(bs, 8);
     842             :                 nbBytes += 5;
     843             :         }
     844             : 
     845        1598 :         while (nbBytes < DescSize) {
     846         215 :                 GF_Descriptor *tmp = NULL;
     847         215 :                 e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
     848         215 :                 if (e) {
     849           0 :                         if (tmp) gf_odf_desc_del((GF_Descriptor *) tmp);
     850           0 :                         return e;
     851             :                 }
     852         215 :                 if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
     853         215 :                 e = AddDescriptorToIsomIOD(iod, tmp);
     854         215 :                 if (e) {
     855           0 :                         gf_odf_desc_del(tmp);
     856           0 :                         return e;
     857             :                 }
     858         215 :                 nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
     859             :         }
     860        1383 :         if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
     861        1383 :         return GF_OK;
     862             : }
     863             : 
     864        2999 : GF_Err gf_odf_size_isom_iod(GF_IsomInitialObjectDescriptor *iod, u32 *outSize)
     865             : {
     866             :         GF_Err e;
     867        2999 :         if (! iod) return GF_BAD_PARAM;
     868             : 
     869        2999 :         *outSize = 2;
     870        2999 :         if (iod->URLString) {
     871           0 :                 *outSize += gf_odf_size_url_string(iod->URLString);
     872             :         } else {
     873        2999 :                 *outSize += 5;
     874        2999 :                 e = gf_odf_size_descriptor_list(iod->ES_ID_IncDescriptors, outSize);
     875        2999 :                 if (e) return e;
     876        2999 :                 e = gf_odf_size_descriptor_list(iod->ES_ID_RefDescriptors, outSize);
     877        2999 :                 if (e) return e;
     878        2999 :                 e = gf_odf_size_descriptor_list(iod->OCIDescriptors, outSize);
     879        2999 :                 if (e) return e;
     880        2999 :                 e = gf_odf_size_descriptor_list(iod->IPMP_Descriptors, outSize);
     881        2999 :                 if (e) return e;
     882             :         }
     883        2999 :         if (iod->IPMPToolList) {
     884             :                 u32 tmpSize;
     885           0 :                 e = gf_odf_size_descriptor((GF_Descriptor *) iod->IPMPToolList, &tmpSize);
     886           0 :                 if (e) return e;
     887           0 :                 *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
     888             :         }
     889        2999 :         return gf_odf_size_descriptor_list(iod->extensionDescriptors, outSize);
     890             : }
     891             : 
     892        1204 : GF_Err gf_odf_write_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *iod)
     893             : {
     894             :         GF_Err e;
     895             :         u32 size;
     896        1204 :         if (! iod) return GF_BAD_PARAM;
     897             : 
     898        1204 :         e = gf_odf_size_descriptor((GF_Descriptor *)iod, &size);
     899        1204 :         if (e) return e;
     900        1204 :         e = gf_odf_write_base_descriptor(bs, iod->tag, size);
     901        1204 :         if (e) return e;
     902             : 
     903        1204 :         gf_bs_write_int(bs, iod->objectDescriptorID, 10);
     904        1204 :         gf_bs_write_int(bs, iod->URLString != NULL ? 1 : 0, 1);
     905        1204 :         gf_bs_write_int(bs, iod->inlineProfileFlag, 1);
     906        1204 :         gf_bs_write_int(bs, 15, 4);             //reserved: 0b1111 == 15
     907             : 
     908        1204 :         if (iod->URLString) {
     909           0 :                 gf_odf_write_url_string(bs, iod->URLString);
     910             :         } else {
     911        1204 :                 gf_bs_write_int(bs, iod->OD_profileAndLevel, 8);
     912        1204 :                 gf_bs_write_int(bs, iod->scene_profileAndLevel, 8);
     913        1204 :                 gf_bs_write_int(bs, iod->audio_profileAndLevel, 8);
     914        1204 :                 gf_bs_write_int(bs, iod->visual_profileAndLevel, 8);
     915        1204 :                 gf_bs_write_int(bs, iod->graphics_profileAndLevel, 8);
     916        1204 :                 e = gf_odf_write_descriptor_list(bs, iod->ES_ID_IncDescriptors);
     917        1204 :                 if (e) return e;
     918        1204 :                 e = gf_odf_write_descriptor_list(bs, iod->ES_ID_RefDescriptors);
     919        1204 :                 if (e) return e;
     920        1204 :                 e = gf_odf_write_descriptor_list(bs, iod->OCIDescriptors);
     921        1204 :                 if (e) return e;
     922        1204 :                 e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
     923        1204 :                 if (e) return e;
     924        1204 :                 e = gf_odf_write_descriptor_list_filter(bs, iod->IPMP_Descriptors, GF_ODF_IPMP_TAG);
     925        1204 :                 if (e) return e;
     926        1204 :                 if (iod->IPMPToolList) {
     927           0 :                         e = gf_odf_write_descriptor(bs, (GF_Descriptor *) iod->IPMPToolList);
     928           0 :                         if (e) return e;
     929             :                 }
     930             :         }
     931        1204 :         e = gf_odf_write_descriptor_list(bs, iod->extensionDescriptors);
     932        1204 :         if (e) return e;
     933        1204 :         return GF_OK;
     934             : }
     935             : 
     936             : 
     937         232 : GF_Descriptor *gf_odf_new_isom_od()
     938             : {
     939         232 :         GF_IsomObjectDescriptor *newDesc = (GF_IsomObjectDescriptor *) gf_malloc(sizeof(GF_IsomObjectDescriptor));
     940         232 :         if (!newDesc) return NULL;
     941             : 
     942         232 :         newDesc->URLString = NULL;
     943         232 :         newDesc->ES_ID_IncDescriptors = gf_list_new();
     944         232 :         newDesc->ES_ID_RefDescriptors = gf_list_new();
     945         232 :         newDesc->OCIDescriptors = gf_list_new();
     946         232 :         newDesc->IPMP_Descriptors = gf_list_new();
     947         232 :         newDesc->extensionDescriptors = gf_list_new();
     948         232 :         newDesc->objectDescriptorID = 0;
     949         232 :         newDesc->tag = GF_ODF_ISOM_OD_TAG;
     950         232 :         return (GF_Descriptor *) newDesc;
     951             : }
     952             : 
     953         349 : GF_Err gf_odf_del_isom_od(GF_IsomObjectDescriptor *od)
     954             : {
     955             :         GF_Err e;
     956         349 :         if (!od) return GF_BAD_PARAM;
     957         349 :         if (od->URLString)   gf_free(od->URLString);
     958         349 :         e = gf_odf_delete_descriptor_list(od->ES_ID_IncDescriptors);
     959         349 :         if (e) return e;
     960         349 :         e = gf_odf_delete_descriptor_list(od->ES_ID_RefDescriptors);
     961         349 :         if (e) return e;
     962         349 :         e = gf_odf_delete_descriptor_list(od->OCIDescriptors);
     963         349 :         if (e) return e;
     964         349 :         e = gf_odf_delete_descriptor_list(od->IPMP_Descriptors);
     965         349 :         if (e) return e;
     966         349 :         e = gf_odf_delete_descriptor_list(od->extensionDescriptors);
     967         349 :         if (e) return e;
     968         349 :         gf_free(od);
     969         349 :         return GF_OK;
     970             : }
     971             : 
     972         341 : GF_Err AddDescriptorToIsomOD(GF_IsomObjectDescriptor *od, GF_Descriptor *desc)
     973             : {
     974         341 :         if (!od || !desc) return GF_BAD_PARAM;
     975             : 
     976             :         //check if we can handle ContentClassif tags
     977         341 :         if ( (desc->tag >= GF_ODF_OCI_BEGIN_TAG) &&
     978             :                 (desc->tag <= GF_ODF_OCI_END_TAG) ) {
     979           0 :                 return gf_list_add(od->OCIDescriptors, desc);
     980             :         }
     981             : 
     982             :         //or extension ...
     983         341 :         if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) &&
     984             :                 (desc->tag <= GF_ODF_EXT_END_TAG) ) {
     985           0 :                 return gf_list_add(od->extensionDescriptors, desc);
     986             :         }
     987             : 
     988         341 :         switch (desc->tag) {
     989             :         case GF_ODF_ESD_TAG:
     990             :                 return GF_ODF_FORBIDDEN_DESCRIPTOR;
     991             : 
     992          36 :         case GF_ODF_ESD_INC_TAG:
     993             :                 //there shouldn't be ref if inc
     994          36 :                 if (gf_list_count(od->ES_ID_RefDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
     995          36 :                 return gf_list_add(od->ES_ID_IncDescriptors, desc);
     996             : 
     997         305 :         case GF_ODF_ESD_REF_TAG:
     998             :                 //there shouldn't be inc if ref
     999         305 :                 if (gf_list_count(od->ES_ID_IncDescriptors)) return GF_ODF_FORBIDDEN_DESCRIPTOR;
    1000         305 :                 return gf_list_add(od->ES_ID_RefDescriptors, desc);
    1001             : 
    1002             :         //we use the same struct for v1 and v2 IPMP DPs
    1003           0 :         case GF_ODF_IPMP_PTR_TAG:
    1004             :         case GF_ODF_IPMP_TAG:
    1005           0 :                 return gf_list_add(od->IPMP_Descriptors, desc);
    1006             : 
    1007           0 :         default:
    1008           0 :                 return GF_BAD_PARAM;
    1009             :         }
    1010             : }
    1011             : 
    1012         196 : GF_Err gf_odf_read_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od, u32 DescSize)
    1013             : {
    1014             :         GF_Err e;
    1015             :         u32 urlflag;
    1016             :         u32 tmpSize, nbBytes = 0;
    1017         196 :         if (! od) return GF_BAD_PARAM;
    1018             : 
    1019         196 :         od->objectDescriptorID = gf_bs_read_int(bs, 10);
    1020         196 :         urlflag = gf_bs_read_int(bs, 1);
    1021         196 :         /*reserved = */gf_bs_read_int(bs, 5);
    1022             :         nbBytes += 2;
    1023             : 
    1024         196 :         if (urlflag) {
    1025             :                 u32 read;
    1026           3 :                 e = gf_odf_read_url_string(bs, & od->URLString, &read);
    1027           3 :                 if (e) return e;
    1028           3 :                 nbBytes += read;
    1029             :         }
    1030             : 
    1031         389 :         while (nbBytes < DescSize) {
    1032         193 :                 GF_Descriptor *tmp = NULL;
    1033         193 :                 e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
    1034         193 :                 if (e) return e;
    1035         193 :                 if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
    1036         193 :                 e = AddDescriptorToIsomOD(od, tmp);
    1037         193 :                 if (e) {
    1038           0 :                         gf_odf_delete_descriptor(tmp);
    1039           0 :                         return e;
    1040             :                 }
    1041         193 :                 nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
    1042             :         }
    1043         196 :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    1044         196 :         return GF_OK;
    1045             : }
    1046             : 
    1047         330 : GF_Err gf_odf_size_isom_od(GF_IsomObjectDescriptor *od, u32 *outSize)
    1048             : {
    1049             :         GF_Err e;
    1050         330 :         if (! od) return GF_BAD_PARAM;
    1051             : 
    1052         330 :         *outSize = 2;
    1053         330 :         if (od->URLString) {
    1054           4 :                 *outSize += gf_odf_size_url_string(od->URLString);
    1055             :         } else {
    1056         326 :                 e = gf_odf_size_descriptor_list(od->ES_ID_IncDescriptors, outSize);
    1057         326 :                 if (e) return e;
    1058         326 :                 e = gf_odf_size_descriptor_list(od->ES_ID_RefDescriptors, outSize);
    1059         326 :                 if (e) return e;
    1060         326 :                 e = gf_odf_size_descriptor_list(od->OCIDescriptors, outSize);
    1061         326 :                 if (e) return e;
    1062         326 :                 e = gf_odf_size_descriptor_list(od->IPMP_Descriptors, outSize);
    1063         326 :                 if (e) return e;
    1064             :         }
    1065         330 :         return gf_odf_size_descriptor_list(od->extensionDescriptors, outSize);
    1066             : }
    1067             : 
    1068         213 : GF_Err gf_odf_write_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od)
    1069             : {
    1070             :         GF_Err e;
    1071             :         u32 size;
    1072         213 :         if (! od) return GF_BAD_PARAM;
    1073             : 
    1074         213 :         e = gf_odf_size_descriptor((GF_Descriptor *)od, &size);
    1075         213 :         if (e) return e;
    1076         213 :         e = gf_odf_write_base_descriptor(bs, od->tag, size);
    1077         213 :         if (e) return e;
    1078             : 
    1079         213 :         gf_bs_write_int(bs, od->objectDescriptorID, 10);
    1080         213 :         gf_bs_write_int(bs, od->URLString != NULL ? 1 : 0, 1);
    1081         213 :         gf_bs_write_int(bs, 31, 5);             //reserved: 0b1111.1 == 31
    1082             : 
    1083         213 :         if (od->URLString) {
    1084           2 :                 gf_odf_write_url_string(bs, od->URLString);
    1085             :         } else {
    1086         211 :                 e = gf_odf_write_descriptor_list(bs, od->ES_ID_IncDescriptors);
    1087         211 :                 if (e) return e;
    1088         211 :                 e = gf_odf_write_descriptor_list(bs, od->ES_ID_RefDescriptors);
    1089         211 :                 if (e) return e;
    1090         211 :                 e = gf_odf_write_descriptor_list(bs, od->OCIDescriptors);
    1091         211 :                 if (e) return e;
    1092         211 :                 e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_PTR_TAG);
    1093         211 :                 if (e) return e;
    1094         211 :                 e = gf_odf_write_descriptor_list_filter(bs, od->IPMP_Descriptors, GF_ODF_IPMP_TAG);
    1095         211 :                 if (e) return e;
    1096             :         }
    1097         213 :         e = gf_odf_write_descriptor_list(bs, od->extensionDescriptors);
    1098         213 :         if (e) return e;
    1099         213 :         return GF_OK;
    1100             : }
    1101             : 
    1102             : 
    1103             : 
    1104        7893 : GF_Descriptor *gf_odf_new_dcd()
    1105             : {
    1106             :         GF_DecoderConfig *newDesc;
    1107        7893 :         GF_SAFEALLOC(newDesc, GF_DecoderConfig);
    1108        7893 :         if (!newDesc) return NULL;
    1109             : 
    1110        7893 :         newDesc->profileLevelIndicationIndexDescriptor = gf_list_new();
    1111        7893 :         newDesc->tag = GF_ODF_DCD_TAG;
    1112        7893 :         return (GF_Descriptor *) newDesc;
    1113             : }
    1114             : 
    1115        7893 : GF_Err gf_odf_del_dcd(GF_DecoderConfig *dcd)
    1116             : {
    1117             :         GF_Err e;
    1118        7893 :         if (!dcd) return GF_BAD_PARAM;
    1119        7893 :         if (dcd->decoderSpecificInfo) {
    1120        7594 :                 e = gf_odf_delete_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo);
    1121        7594 :                 if (e) return e;
    1122             :         }
    1123        7893 :         if (dcd->rvc_config) {
    1124           0 :                 e = gf_odf_delete_descriptor((GF_Descriptor *) dcd->rvc_config);
    1125           0 :                 if (e) return e;
    1126             :         }
    1127        7893 :         e = gf_odf_delete_descriptor_list(dcd->profileLevelIndicationIndexDescriptor);
    1128        7893 :         if (e) return e;
    1129        7893 :         gf_free(dcd);
    1130        7893 :         return GF_OK;
    1131             : }
    1132             : 
    1133        3752 : GF_Err gf_odf_read_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd, u32 DescSize)
    1134             : {
    1135             :         GF_Err e;
    1136             :         u32 /*reserved, */tmp_size, nbBytes = 0;
    1137        3752 :         if (! dcd) return GF_BAD_PARAM;
    1138             : 
    1139        3752 :         dcd->objectTypeIndication = gf_bs_read_int(bs, 8);
    1140        3752 :         dcd->streamType = gf_bs_read_int(bs, 6);
    1141        3752 :         dcd->upstream = gf_bs_read_int(bs, 1);
    1142        3752 :         /*reserved = */gf_bs_read_int(bs, 1);
    1143        3752 :         dcd->bufferSizeDB = gf_bs_read_int(bs, 24);
    1144        3752 :         dcd->maxBitrate = gf_bs_read_int(bs, 32);
    1145        3752 :         dcd->avgBitrate = gf_bs_read_int(bs, 32);
    1146             :         nbBytes += 13;
    1147             : 
    1148       11108 :         while (nbBytes < DescSize) {
    1149        3604 :                 GF_Descriptor *tmp = NULL;
    1150        3604 :                 e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size);
    1151        3604 :                 if (e) return e;
    1152        3604 :                 if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
    1153        3604 :                 switch (tmp->tag) {
    1154        3604 :                 case GF_ODF_DSI_TAG:
    1155        3604 :                         if (dcd->decoderSpecificInfo) {
    1156           0 :                                 gf_odf_delete_descriptor(tmp);
    1157           0 :                                 return GF_ODF_INVALID_DESCRIPTOR;
    1158             :                         }
    1159        3604 :                         dcd->decoderSpecificInfo = (GF_DefaultDescriptor *) tmp;
    1160        3604 :                         break;
    1161             : 
    1162           0 :                 case GF_ODF_EXT_PL_TAG:
    1163           0 :                         e = gf_list_add(dcd->profileLevelIndicationIndexDescriptor, tmp);
    1164           0 :                         if (e < GF_OK) {
    1165           0 :                                 gf_odf_delete_descriptor(tmp);
    1166           0 :                                 return e;
    1167             :                         }
    1168             :                         break;
    1169             : 
    1170             :                 /*iPod fix: delete and aborts, this will create an InvalidDescriptor at the ESD level with a loaded DSI,
    1171             :                 loading will abort with a partially valid ESD which is all the matters*/
    1172           0 :                 case GF_ODF_SLC_TAG:
    1173           0 :                         gf_odf_delete_descriptor(tmp);
    1174           0 :                         return GF_OK;
    1175             : 
    1176             :                 //what the hell is this descriptor ?? Don't know, so delete it !
    1177           0 :                 default:
    1178           0 :                         gf_odf_delete_descriptor(tmp);
    1179           0 :                         break;
    1180             :                 }
    1181        3604 :                 nbBytes += tmp_size + gf_odf_size_field_size(tmp_size);
    1182             :         }
    1183        3752 :         if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
    1184        3752 :         return GF_OK;
    1185             : }
    1186             : 
    1187             : #include <gpac/constants.h>
    1188             : 
    1189        9753 : GF_Err gf_odf_size_dcd(GF_DecoderConfig *dcd, u32 *outSize)
    1190             : {
    1191             :         GF_Err e;
    1192             :         u32 tmpSize;
    1193             :         u32 oti;
    1194        9753 :         if (! dcd) return GF_BAD_PARAM;
    1195             : 
    1196        9753 :         oti = dcd->objectTypeIndication;
    1197        9753 :         if (oti > 0xFF) {
    1198           0 :                 oti = gf_codecid_oti(oti);
    1199             :         }
    1200        9753 :         if (oti > 0xFF) {
    1201           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Attempt to write an internal ESD with codec ID %s (%s) , not mappable to 8 bits MPEG-4 Systems OTI", gf_4cc_to_str(dcd->objectTypeIndication), gf_codecid_name(dcd->objectTypeIndication) ));
    1202             :                 return GF_BAD_PARAM;
    1203             :         }
    1204             : 
    1205             :         *outSize = 0;
    1206        9753 :         *outSize += 13;
    1207        9753 :         if (dcd->decoderSpecificInfo) {
    1208             :                 //warning: we don't know anything about the structure of a generic DecSpecInfo
    1209             :                 //we check the tag and size of the descriptor, but we most ofthe time can't parse it
    1210             :                 //the decSpecInfo is handle as a defaultDescriptor (opaque data, but same structure....)
    1211        9401 :                 e = gf_odf_size_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo , &tmpSize);
    1212        9401 :                 if (e) return e;
    1213        9401 :                 *outSize += tmpSize + gf_odf_size_field_size(tmpSize);
    1214             :         }
    1215        9753 :         e = gf_odf_size_descriptor_list(dcd->profileLevelIndicationIndexDescriptor, outSize);
    1216        9753 :         if (e) return e;
    1217        9753 :         return GF_OK;
    1218             : }
    1219             : 
    1220        3637 : GF_Err gf_odf_write_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd)
    1221             : {
    1222             :         GF_Err e;
    1223             :         u32 size, oti;
    1224        3637 :         if (! dcd) return GF_BAD_PARAM;
    1225             :         
    1226        3637 :         oti = dcd->objectTypeIndication;
    1227        3637 :         if (oti > 0xFF) {
    1228           0 :                 oti = gf_codecid_oti(oti);
    1229             :         }
    1230        3637 :         if (oti > 0xFF) {
    1231           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[ODF] Attempt to write an internal ESD with codec ID %s (%s) , not mappable to 8 bits MPEG-4 Systems OTI", gf_4cc_to_str(dcd->objectTypeIndication), gf_codecid_name(dcd->objectTypeIndication) ));
    1232             :                 return GF_BAD_PARAM;
    1233             :         }
    1234             : 
    1235        3637 :         e = gf_odf_size_descriptor((GF_Descriptor *)dcd, &size);
    1236        3637 :         if (e) return e;
    1237        3637 :         e = gf_odf_write_base_descriptor(bs, dcd->tag, size);
    1238        3637 :         if (e) return e;
    1239             : 
    1240        3637 :         gf_bs_write_int(bs, oti, 8);
    1241        3637 :         gf_bs_write_int(bs, dcd->streamType, 6);
    1242        3637 :         gf_bs_write_int(bs, dcd->upstream, 1);
    1243        3637 :         gf_bs_write_int(bs, 1, 1);      //reserved field...
    1244        3637 :         gf_bs_write_int(bs, dcd->bufferSizeDB, 24);
    1245        3637 :         gf_bs_write_int(bs, dcd->maxBitrate, 32);
    1246        3637 :         gf_bs_write_int(bs, dcd->avgBitrate, 32);
    1247             : 
    1248        3637 :         if (dcd->decoderSpecificInfo) {
    1249        3499 :                 e = gf_odf_write_descriptor(bs, (GF_Descriptor *) dcd->decoderSpecificInfo);
    1250        3499 :                 if (e) return e;
    1251             :         }
    1252        3637 :         e = gf_odf_write_descriptor_list(bs, dcd->profileLevelIndicationIndexDescriptor);
    1253        3637 :         return e;
    1254             : }
    1255             : 
    1256             : 
    1257        7264 : GF_Descriptor *gf_odf_new_default()
    1258             : {
    1259        7264 :         GF_DefaultDescriptor *newDesc = (GF_DefaultDescriptor *) gf_malloc(sizeof(GF_DefaultDescriptor));
    1260        7264 :         if (!newDesc) return NULL;
    1261             : 
    1262        7264 :         newDesc->dataLength = 0;
    1263        7264 :         newDesc->data = NULL;
    1264             :         //set it to the Max allowed
    1265        7264 :         newDesc->tag = GF_ODF_USER_END_TAG;
    1266        7264 :         return (GF_Descriptor *) newDesc;
    1267             : }
    1268             : 
    1269        7264 : GF_Err gf_odf_del_default(GF_DefaultDescriptor *dd)
    1270             : {
    1271        7264 :         if (!dd) return GF_BAD_PARAM;
    1272             : 
    1273        7264 :         if (dd->data) gf_free(dd->data);
    1274        7264 :         gf_free(dd);
    1275        7264 :         return GF_OK;
    1276             : }
    1277             : 
    1278        3604 : GF_Err gf_odf_read_default(GF_BitStream *bs, GF_DefaultDescriptor *dd, u32 DescSize)
    1279             : {
    1280             :         u32 nbBytes = 0;
    1281        3604 :         if (! dd) return GF_BAD_PARAM;
    1282             : 
    1283        3604 :         dd->dataLength = DescSize;
    1284        3604 :         dd->data = NULL;
    1285        3604 :         if (DescSize) {
    1286        3213 :                 dd->data = (char*)gf_malloc(dd->dataLength);
    1287        3213 :                 if (! dd->data) return GF_OUT_OF_MEM;
    1288        3213 :                 gf_bs_read_data(bs, dd->data, dd->dataLength);
    1289        3213 :                 nbBytes += dd->dataLength;
    1290             :                 /* internal tags are read as default but deleted as their own types
    1291             :                    so dd->data would leak here */
    1292        3213 :                 if ((dd->tag>=GF_ODF_MUXINFO_TAG) && (dd->tag<=GF_ODF_LASER_CFG_TAG)) {
    1293           0 :                         gf_free(dd->data);
    1294           0 :                         dd->data = NULL;
    1295             :                 }
    1296             :         }
    1297        3604 :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    1298        3604 :         return GF_OK;
    1299             : }
    1300             : 
    1301       12900 : GF_Err gf_odf_size_default(GF_DefaultDescriptor *dd, u32 *outSize)
    1302             : {
    1303       12900 :         if (! dd) return GF_BAD_PARAM;
    1304       12900 :         *outSize  = dd->dataLength;
    1305       12900 :         return GF_OK;
    1306             : }
    1307             : 
    1308        3499 : GF_Err gf_odf_write_default(GF_BitStream *bs, GF_DefaultDescriptor *dd)
    1309             : {
    1310             :         GF_Err e;
    1311             :         u32 size;
    1312        3499 :         if (! dd) return GF_BAD_PARAM;
    1313             : 
    1314        3499 :         e = gf_odf_size_descriptor((GF_Descriptor *)dd, &size);
    1315        3499 :         if (e) return e;
    1316        3499 :         e = gf_odf_write_base_descriptor(bs, dd->tag, size);
    1317        3499 :         if (e) return e;
    1318             : 
    1319        3499 :         if (dd->data) {
    1320        3101 :                 gf_bs_write_data(bs, dd->data, dd->dataLength);
    1321             :         }
    1322             :         return GF_OK;
    1323             : }
    1324             : 
    1325         391 : GF_Descriptor *gf_odf_new_esd_inc()
    1326             : {
    1327         391 :         GF_ES_ID_Inc *newDesc = (GF_ES_ID_Inc *) gf_malloc(sizeof(GF_ES_ID_Inc));
    1328         391 :         if (!newDesc) return NULL;
    1329         391 :         newDesc->tag = GF_ODF_ESD_INC_TAG;
    1330         391 :         newDesc->trackID = 0;
    1331         391 :         return (GF_Descriptor *) newDesc;
    1332             : }
    1333             : 
    1334         391 : GF_Err gf_odf_del_esd_inc(GF_ES_ID_Inc *esd_inc)
    1335             : {
    1336         391 :         if (!esd_inc) return GF_BAD_PARAM;
    1337         391 :         gf_free(esd_inc);
    1338         391 :         return GF_OK;
    1339             : }
    1340         297 : GF_Err gf_odf_read_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc, u32 DescSize)
    1341             : {
    1342             :         u32 nbBytes = 0;
    1343         297 :         if (! esd_inc) return GF_BAD_PARAM;
    1344             : 
    1345         297 :         esd_inc->trackID = gf_bs_read_int(bs, 32);
    1346             :         nbBytes += 4;
    1347         297 :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    1348         297 :         return GF_OK;
    1349             : }
    1350         775 : GF_Err gf_odf_size_esd_inc(GF_ES_ID_Inc *esd_inc, u32 *outSize)
    1351             : {
    1352         775 :         if (! esd_inc) return GF_BAD_PARAM;
    1353         775 :         *outSize = 4;
    1354         775 :         return GF_OK;
    1355             : }
    1356         284 : GF_Err gf_odf_write_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc)
    1357             : {
    1358             :         GF_Err e;
    1359             :         u32 size;
    1360         284 :         if (! esd_inc) return GF_BAD_PARAM;
    1361             : 
    1362         284 :         e = gf_odf_size_descriptor((GF_Descriptor *)esd_inc, &size);
    1363         284 :         if (e) return e;
    1364         284 :         e = gf_odf_write_base_descriptor(bs, esd_inc->tag, size);
    1365         284 :         if (e) return e;
    1366         284 :         gf_bs_write_int(bs, esd_inc->trackID, 32);
    1367         284 :         return GF_OK;
    1368             : }
    1369             : 
    1370         314 : GF_Descriptor *gf_odf_new_esd_ref()
    1371             : {
    1372         314 :         GF_ES_ID_Ref *newDesc = (GF_ES_ID_Ref *) gf_malloc(sizeof(GF_ES_ID_Ref));
    1373         314 :         if (!newDesc) return NULL;
    1374         314 :         newDesc->tag = GF_ODF_ESD_REF_TAG;
    1375         314 :         newDesc->trackRef = 0;
    1376         314 :         return (GF_Descriptor *) newDesc;
    1377             : }
    1378             : 
    1379         314 : GF_Err gf_odf_del_esd_ref(GF_ES_ID_Ref *esd_ref)
    1380             : {
    1381         314 :         if (!esd_ref) return GF_BAD_PARAM;
    1382         314 :         gf_free(esd_ref);
    1383         314 :         return GF_OK;
    1384             : }
    1385         199 : GF_Err gf_odf_read_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref, u32 DescSize)
    1386             : {
    1387             :         u32 nbBytes = 0;
    1388         199 :         if (! esd_ref) return GF_BAD_PARAM;
    1389             : 
    1390         199 :         esd_ref->trackRef = gf_bs_read_int(bs, 16);
    1391             :         nbBytes += 2;
    1392         199 :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    1393         199 :         return GF_OK;
    1394             : }
    1395             : 
    1396         534 : GF_Err gf_odf_size_esd_ref(GF_ES_ID_Ref *esd_ref, u32 *outSize)
    1397             : {
    1398         534 :         if (! esd_ref) return GF_BAD_PARAM;
    1399         534 :         *outSize = 2;
    1400         534 :         return GF_OK;
    1401             : }
    1402         211 : GF_Err gf_odf_write_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref)
    1403             : {
    1404             :         GF_Err e;
    1405             :         u32 size;
    1406         211 :         if (! esd_ref) return GF_BAD_PARAM;
    1407             : 
    1408         211 :         e = gf_odf_size_descriptor((GF_Descriptor *)esd_ref, &size);
    1409         211 :         if (e) return e;
    1410         211 :         e = gf_odf_write_base_descriptor(bs, esd_ref->tag, size);
    1411         211 :         if (e) return e;
    1412             : 
    1413         211 :         gf_bs_write_int(bs, esd_ref->trackRef, 16);
    1414         211 :         return GF_OK;
    1415             : }
    1416             : 
    1417             : 
    1418             : 
    1419          33 : GF_Descriptor *gf_odf_new_segment()
    1420             : {
    1421          33 :         GF_Segment *newDesc = (GF_Segment *) gf_malloc(sizeof(GF_Segment));
    1422          33 :         if (!newDesc) return NULL;
    1423             : 
    1424             :         memset(newDesc, 0, sizeof(GF_Segment));
    1425          33 :         newDesc->tag = GF_ODF_SEGMENT_TAG;
    1426          33 :         return (GF_Descriptor *) newDesc;
    1427             : }
    1428             : 
    1429          33 : GF_Err gf_odf_del_segment(GF_Segment *sd)
    1430             : {
    1431          33 :         if (!sd) return GF_BAD_PARAM;
    1432             : 
    1433          33 :         if (sd->SegmentName) gf_free(sd->SegmentName);
    1434          33 :         gf_free(sd);
    1435          33 :         return GF_OK;
    1436             : }
    1437             : 
    1438          18 : GF_Err gf_odf_read_segment(GF_BitStream *bs, GF_Segment *sd, u32 DescSize)
    1439             : {
    1440             :         u32 size, nbBytes = 0;
    1441          18 :         if (!sd) return GF_BAD_PARAM;
    1442             : 
    1443          18 :         sd->startTime = gf_bs_read_double(bs);
    1444          18 :         sd->Duration = gf_bs_read_double(bs);
    1445             :         nbBytes += 16;
    1446          18 :         size = gf_bs_read_int(bs, 8);
    1447             :         nbBytes += 1;
    1448          18 :         if (size) {
    1449          18 :                 sd->SegmentName = (char*) gf_malloc(sizeof(char)*(size+1));
    1450          18 :                 if (!sd->SegmentName) return GF_OUT_OF_MEM;
    1451          18 :                 gf_bs_read_data(bs, sd->SegmentName, size);
    1452          18 :                 sd->SegmentName[size] = 0;
    1453          18 :                 nbBytes += size;
    1454             :         }
    1455          18 :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    1456          18 :         return GF_OK;
    1457             : }
    1458             : 
    1459          48 : GF_Err gf_odf_size_segment(GF_Segment *sd, u32 *outSize)
    1460             : {
    1461          48 :         if (!sd) return GF_BAD_PARAM;
    1462          48 :         *outSize = 17;
    1463          48 :         if (sd->SegmentName) *outSize += (u32) strlen(sd->SegmentName);
    1464             :         return GF_OK;
    1465             : }
    1466             : 
    1467          18 : GF_Err gf_odf_write_segment(GF_BitStream *bs, GF_Segment *sd)
    1468             : {
    1469             :         GF_Err e;
    1470             :         u32 size;
    1471          18 :         if (!sd) return GF_BAD_PARAM;
    1472          18 :         e = gf_odf_size_descriptor((GF_Descriptor *)sd, &size);
    1473          18 :         if (e) return e;
    1474          18 :         e = gf_odf_write_base_descriptor(bs, sd->tag, size);
    1475          18 :         if (e) return e;
    1476          18 :         gf_bs_write_double(bs, sd->startTime);
    1477          18 :         gf_bs_write_double(bs, sd->Duration);
    1478          18 :         if (sd->SegmentName) {
    1479          18 :                 gf_bs_write_int(bs, (u32) strlen(sd->SegmentName), 8);
    1480          18 :                 gf_bs_write_data(bs, sd->SegmentName, (u32) strlen(sd->SegmentName));
    1481             :         } else {
    1482           0 :                 gf_bs_write_int(bs, 0, 8);
    1483             :         }
    1484             :         return GF_OK;
    1485             : }
    1486             : 
    1487             : 
    1488             : 
    1489         329 : GF_Descriptor *gf_odf_new_lang()
    1490             : {
    1491             :         GF_Language *newDesc;
    1492         329 :         GF_SAFEALLOC(newDesc, GF_Language);
    1493         329 :         if (!newDesc) return NULL;
    1494         329 :         newDesc->tag = GF_ODF_LANG_TAG;
    1495         329 :         return (GF_Descriptor *) newDesc;
    1496             : }
    1497             : 
    1498         329 : GF_Err gf_odf_del_lang(GF_Language *ld)
    1499             : {
    1500         329 :         if (!ld) return GF_BAD_PARAM;
    1501         329 :         if (ld->full_lang_code) gf_free(ld->full_lang_code);
    1502         329 :         gf_free(ld);
    1503         329 :         return GF_OK;
    1504             : }
    1505             : 
    1506          19 : GF_Err gf_odf_read_lang(GF_BitStream *bs, GF_Language *ld, u32 DescSize)
    1507             : {
    1508             :         u32 nbBytes = 0;
    1509          19 :         if (!ld) return GF_BAD_PARAM;
    1510             : 
    1511          19 :         ld->langCode = gf_bs_read_int(bs, 24);
    1512             :         nbBytes += 3;
    1513          19 :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    1514          19 :         return GF_OK;
    1515             : }
    1516             : 
    1517          33 : GF_Err gf_odf_size_lang(GF_Language *ld, u32 *outSize)
    1518             : {
    1519          33 :         if (!ld) return GF_BAD_PARAM;
    1520          33 :         *outSize = 3;
    1521          33 :         return GF_OK;
    1522             : }
    1523             : 
    1524          15 : GF_Err gf_odf_write_lang(GF_BitStream *bs, GF_Language *ld)
    1525             : {
    1526             :         GF_Err e;
    1527             :         u32 size;
    1528          15 :         if (!ld) return GF_BAD_PARAM;
    1529             : 
    1530          15 :         e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size);
    1531          15 :         if (e) return e;
    1532          15 :         e = gf_odf_write_base_descriptor(bs, ld->tag, size);
    1533          15 :         if (e) return e;
    1534          15 :         gf_bs_write_int(bs, ld->langCode, 24);
    1535          15 :         return GF_OK;
    1536             : }
    1537             : 
    1538             : 
    1539             : 
    1540          10 : GF_Descriptor *gf_odf_new_auxvid()
    1541             : {
    1542             :         GF_AuxVideoDescriptor *newDesc;
    1543          10 :         GF_SAFEALLOC(newDesc, GF_AuxVideoDescriptor);
    1544          10 :         if (!newDesc) return NULL;
    1545          10 :         newDesc->tag = GF_ODF_AUX_VIDEO_DATA;
    1546          10 :         return (GF_Descriptor *) newDesc;
    1547             : }
    1548             : 
    1549          10 : GF_Err gf_odf_del_auxvid(GF_AuxVideoDescriptor *ld)
    1550             : {
    1551          10 :         if (!ld) return GF_BAD_PARAM;
    1552          10 :         gf_free(ld);
    1553          10 :         return GF_OK;
    1554             : }
    1555             : 
    1556           2 : GF_Err gf_odf_read_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld, u32 DescSize)
    1557             : {
    1558             :         u32 nbBytes = 0;
    1559           2 :         if (!ld) return GF_BAD_PARAM;
    1560             : 
    1561           2 :         ld->aux_video_type = gf_bs_read_int(bs, 8);
    1562           2 :         ld->position_offset_h = gf_bs_read_int(bs, 8);
    1563           2 :         ld->position_offset_v = gf_bs_read_int(bs, 8);
    1564             :         nbBytes += 3;
    1565           2 :         switch (ld->aux_video_type) {
    1566           0 :         case 0x10:
    1567           0 :                 ld->kfar = gf_bs_read_int(bs, 8);
    1568           0 :                 ld->knear = gf_bs_read_int(bs, 8);
    1569             :                 nbBytes += 2;
    1570           0 :                 break;
    1571           0 :         case 0x11:
    1572           0 :                 ld->parallax_zero = gf_bs_read_int(bs, 16);
    1573           0 :                 ld->parallax_scale = gf_bs_read_int(bs, 16);
    1574           0 :                 ld->dref = gf_bs_read_int(bs, 16);
    1575           0 :                 ld->wref = gf_bs_read_int(bs, 16);
    1576             :                 nbBytes += 8;
    1577           0 :                 break;
    1578             :         }
    1579           2 :         while (nbBytes < DescSize) {
    1580           0 :                 gf_bs_read_int(bs, 8);
    1581           0 :                 nbBytes ++;
    1582             :         }
    1583             :         return GF_OK;
    1584             : }
    1585             : 
    1586           8 : GF_Err gf_odf_size_auxvid(GF_AuxVideoDescriptor *ld, u32 *outSize)
    1587             : {
    1588           8 :         if (!ld) return GF_BAD_PARAM;
    1589           8 :         switch (ld->aux_video_type) {
    1590           0 :         case 0x10:
    1591           0 :                 *outSize = 5;
    1592           0 :                 break;
    1593           0 :         case 0x11:
    1594           0 :                 *outSize = 11;
    1595           0 :                 break;
    1596           8 :         default:
    1597           8 :                 *outSize = 3;
    1598           8 :                 break;
    1599             :         }
    1600             :         return GF_OK;
    1601             : }
    1602             : 
    1603           2 : GF_Err gf_odf_write_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld)
    1604             : {
    1605             :         GF_Err e;
    1606             :         u32 size;
    1607           2 :         if (!ld) return GF_BAD_PARAM;
    1608           2 :         e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size);
    1609           2 :         if (e) return e;
    1610           2 :         e = gf_odf_write_base_descriptor(bs, ld->tag, size);
    1611           2 :         if (e) return e;
    1612             : 
    1613           2 :         gf_bs_write_int(bs, ld->aux_video_type, 8);
    1614           2 :         gf_bs_write_int(bs, ld->position_offset_h, 8);
    1615           2 :         gf_bs_write_int(bs, ld->position_offset_v, 8);
    1616           2 :         switch (ld->aux_video_type) {
    1617           0 :         case 0x10:
    1618           0 :                 gf_bs_write_int(bs, ld->kfar, 8);
    1619           0 :                 gf_bs_write_int(bs, ld->knear, 8);
    1620           0 :                 break;
    1621           0 :         case 0x11:
    1622           0 :                 gf_bs_write_int(bs, ld->parallax_zero, 16);
    1623           0 :                 gf_bs_write_int(bs, ld->parallax_scale, 16);
    1624           0 :                 gf_bs_write_int(bs, ld->dref, 16);
    1625           0 :                 gf_bs_write_int(bs, ld->wref, 16);
    1626           0 :                 break;
    1627             :         }
    1628             :         return GF_OK;
    1629             : }
    1630             : 
    1631             : 
    1632             : 
    1633         245 : GF_Descriptor *gf_odf_new_muxinfo()
    1634             : {
    1635         245 :         GF_MuxInfo *newDesc = (GF_MuxInfo *) gf_malloc(sizeof(GF_MuxInfo));
    1636         245 :         if (!newDesc) return NULL;
    1637             :         memset(newDesc, 0, sizeof(GF_MuxInfo));
    1638         245 :         newDesc->tag = GF_ODF_MUXINFO_TAG;
    1639         245 :         return (GF_Descriptor *) newDesc;
    1640             : }
    1641             : 
    1642         245 : GF_Err gf_odf_del_muxinfo(GF_MuxInfo *mi)
    1643             : {
    1644         245 :         if (!mi) return GF_BAD_PARAM;
    1645         245 :         if (mi->file_name) gf_free(mi->file_name);
    1646         245 :         if (mi->src_url) gf_free(mi->src_url);
    1647         245 :         if (mi->streamFormat) gf_free(mi->streamFormat);
    1648         245 :         if (mi->textNode) gf_free(mi->textNode);
    1649         245 :         if (mi->fontNode) gf_free(mi->fontNode);
    1650         245 :         gf_free(mi);
    1651         245 :         return GF_OK;
    1652             : }
    1653             : 
    1654         156 : GF_Err gf_odf_size_muxinfo(GF_MuxInfo *mi, u32 *outSize)
    1655             : {
    1656         156 :         *outSize = 0;
    1657         156 :         return GF_OK;
    1658             : }
    1659          55 : GF_Err gf_odf_write_muxinfo(GF_BitStream *bs, GF_MuxInfo *mi)
    1660             : {
    1661          55 :         return GF_OK;
    1662             : }
    1663             : 
    1664           1 : GF_Descriptor *gf_odf_New_ElemMask()
    1665             : {
    1666           1 :         GF_ElementaryMask *newDesc = (GF_ElementaryMask*) gf_malloc (sizeof(GF_ElementaryMask));
    1667           1 :         if (!newDesc) return NULL;
    1668             :         memset(newDesc, 0, sizeof(GF_ElementaryMask));
    1669           1 :         newDesc->tag = GF_ODF_ELEM_MASK_TAG;
    1670           1 :         return (GF_Descriptor *) newDesc;
    1671             : }
    1672             : 
    1673           1 : GF_Err gf_odf_del_ElemMask(GF_ElementaryMask *desc)
    1674             : {
    1675           1 :         if (desc->node_name) gf_free(desc->node_name);
    1676           1 :         gf_free(desc);
    1677           1 :         return GF_OK;
    1678             : }
    1679             : 
    1680         421 : GF_Descriptor *gf_odf_new_bifs_cfg()
    1681             : {
    1682         421 :         GF_BIFSConfig *newDesc = (GF_BIFSConfig *) gf_malloc(sizeof(GF_BIFSConfig));
    1683         421 :         if (!newDesc) return NULL;
    1684             :         memset(newDesc, 0, sizeof(GF_BIFSConfig));
    1685         421 :         newDesc->tag = GF_ODF_BIFS_CFG_TAG;
    1686         421 :         return (GF_Descriptor *) newDesc;
    1687             : }
    1688             : 
    1689         421 : GF_Err gf_odf_del_bifs_cfg(GF_BIFSConfig *desc)
    1690             : {
    1691         421 :         if (desc->elementaryMasks) {
    1692           0 :                 u32 i, count = gf_list_count(desc->elementaryMasks);
    1693           0 :                 for (i=0; i<count; i++) {
    1694           0 :                         GF_ElementaryMask *tmp = (GF_ElementaryMask *)gf_list_get(desc->elementaryMasks, i);
    1695           0 :                         if (tmp->node_name) gf_free(tmp->node_name);
    1696           0 :                         gf_free(tmp);
    1697             :                 }
    1698           0 :                 gf_list_del(desc->elementaryMasks);
    1699             :         }
    1700         421 :         gf_free(desc);
    1701         421 :         return GF_OK;
    1702             : }
    1703             : 
    1704           2 : GF_Descriptor *gf_odf_new_laser_cfg()
    1705             : {
    1706           2 :         GF_LASERConfig *newDesc = (GF_LASERConfig *) gf_malloc(sizeof(GF_LASERConfig));
    1707           2 :         if (!newDesc) return NULL;
    1708             :         memset(newDesc, 0, sizeof(GF_LASERConfig));
    1709           2 :         newDesc->tag = GF_ODF_LASER_CFG_TAG;
    1710           2 :         return (GF_Descriptor *) newDesc;
    1711             : }
    1712             : 
    1713           2 : GF_Err gf_odf_del_laser_cfg(GF_LASERConfig *desc)
    1714             : {
    1715           2 :         gf_free(desc);
    1716           2 :         return GF_OK;
    1717             : }
    1718             : 
    1719          33 : GF_Descriptor *gf_odf_new_ui_cfg()
    1720             : {
    1721          33 :         GF_UIConfig *newDesc = (GF_UIConfig *) gf_malloc(sizeof(GF_UIConfig));
    1722          33 :         if (!newDesc) return NULL;
    1723             :         memset(newDesc, 0, sizeof(GF_UIConfig));
    1724          33 :         newDesc->tag = GF_ODF_UI_CFG_TAG;
    1725          33 :         return (GF_Descriptor *) newDesc;
    1726             : }
    1727             : 
    1728          33 : GF_Err gf_odf_del_ui_cfg(GF_UIConfig *desc)
    1729             : {
    1730          33 :         if (desc->deviceName) gf_free(desc->deviceName);
    1731          33 :         if (desc->ui_data) gf_free(desc->ui_data);
    1732          33 :         gf_free(desc);
    1733          33 :         return GF_OK;
    1734             : }
    1735             : 
    1736             : #ifndef GPAC_MINIMAL_ODF
    1737             : 
    1738             : GF_Descriptor *gf_odf_new_mediatime()
    1739             : {
    1740             :         GF_MediaTime *newDesc = (GF_MediaTime *) gf_malloc(sizeof(GF_MediaTime));
    1741             :         if (!newDesc) return NULL;
    1742             : 
    1743             :         memset(newDesc, 0, sizeof(GF_MediaTime));
    1744             :         newDesc->tag = GF_ODF_MEDIATIME_TAG;
    1745             :         return (GF_Descriptor *) newDesc;
    1746             : }
    1747             : GF_Err gf_odf_del_mediatime(GF_MediaTime *mt)
    1748             : {
    1749             :         if (!mt) return GF_BAD_PARAM;
    1750             :         gf_free(mt);
    1751             :         return GF_OK;
    1752             : }
    1753             : GF_Err gf_odf_read_mediatime(GF_BitStream *bs, GF_MediaTime *mt, u32 DescSize)
    1754             : {
    1755             :         if (!mt) return GF_BAD_PARAM;
    1756             :         mt->mediaTimeStamp = gf_bs_read_double(bs);
    1757             :         return GF_OK;
    1758             : }
    1759             : GF_Err gf_odf_size_mediatime(GF_MediaTime *mt, u32 *outSize)
    1760             : {
    1761             :         if (!mt) return GF_BAD_PARAM;
    1762             :         *outSize = 8;
    1763             :         return GF_OK;
    1764             : }
    1765             : GF_Err gf_odf_write_mediatime(GF_BitStream *bs, GF_MediaTime *mt)
    1766             : {
    1767             :         GF_Err e;
    1768             :         u32 size;
    1769             :         if (!mt) return GF_BAD_PARAM;
    1770             :         e = gf_odf_size_descriptor((GF_Descriptor *)mt, &size);
    1771             :         if (e) return e;
    1772             :         e = gf_odf_write_base_descriptor(bs, mt->tag, size);
    1773             :         if (e) return e;
    1774             :         gf_bs_write_double(bs, mt->mediaTimeStamp);
    1775             :         return GF_OK;
    1776             : }
    1777             : 
    1778             : GF_Descriptor *gf_odf_new_cc()
    1779             : {
    1780             :         GF_CCDescriptor *newDesc = (GF_CCDescriptor *) gf_malloc(sizeof(GF_CCDescriptor));
    1781             :         if (!newDesc) return NULL;
    1782             : 
    1783             :         newDesc->contentClassificationData = NULL;
    1784             :         newDesc->dataLength = 0;
    1785             :         newDesc->classificationEntity = 0;
    1786             :         newDesc->classificationTable = 0;
    1787             :         newDesc->tag = GF_ODF_CC_TAG;
    1788             :         return (GF_Descriptor *) newDesc;
    1789             : }
    1790             : 
    1791             : GF_Err gf_odf_del_cc(GF_CCDescriptor *ccd)
    1792             : {
    1793             :         if (!ccd) return GF_BAD_PARAM;
    1794             :         if (ccd->contentClassificationData) gf_free(ccd->contentClassificationData);
    1795             :         gf_free(ccd);
    1796             :         return GF_OK;
    1797             : }
    1798             : 
    1799             : GF_Err gf_odf_read_cc(GF_BitStream *bs, GF_CCDescriptor *ccd, u32 DescSize)
    1800             : {
    1801             :         u32 nbBytes = 0;
    1802             :         if (!ccd) return GF_BAD_PARAM;
    1803             : 
    1804             :         ccd->classificationEntity = gf_bs_read_int(bs, 32);
    1805             :         ccd->classificationTable = gf_bs_read_int(bs, 16);
    1806             :         nbBytes += 6;
    1807             :         if (DescSize < 6) return GF_ODF_INVALID_DESCRIPTOR;
    1808             : 
    1809             :         ccd->dataLength = DescSize - 6;
    1810             :         ccd->contentClassificationData = (char*)gf_malloc(sizeof(char) * ccd->dataLength);
    1811             :         if (!ccd->contentClassificationData) return GF_OUT_OF_MEM;
    1812             :         gf_bs_read_data(bs, ccd->contentClassificationData, ccd->dataLength);
    1813             :         nbBytes += ccd->dataLength;
    1814             : 
    1815             :         if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
    1816             :         return GF_OK;
    1817             : }
    1818             : 
    1819             : GF_Err gf_odf_size_cc(GF_CCDescriptor *ccd, u32 *outSize)
    1820             : {
    1821             :         if (!ccd) return GF_BAD_PARAM;
    1822             :         *outSize = 6 + ccd->dataLength;
    1823             :         return GF_OK;
    1824             : }
    1825             : 
    1826             : GF_Err gf_odf_write_cc(GF_BitStream *bs, GF_CCDescriptor *ccd)
    1827             : {
    1828             :         u32 size;
    1829             :         GF_Err e;
    1830             :         if (!ccd) return GF_BAD_PARAM;
    1831             : 
    1832             :         e = gf_odf_size_descriptor((GF_Descriptor *)ccd, &size);
    1833             :         if (e) return e;
    1834             :         e = gf_odf_write_base_descriptor(bs, ccd->tag, size);
    1835             :         if (e) return e;
    1836             :         gf_bs_write_int(bs, ccd->classificationEntity, 32);
    1837             :         gf_bs_write_int(bs, ccd->classificationTable, 16);
    1838             :         gf_bs_write_data(bs, ccd->contentClassificationData, ccd->dataLength);
    1839             :         return GF_OK;
    1840             : }
    1841             : 
    1842             : GF_Descriptor *gf_odf_new_cc_date()
    1843             : {
    1844             :         GF_CC_Date *newDesc = (GF_CC_Date *) gf_malloc(sizeof(GF_CC_Date));
    1845             :         if (!newDesc) return NULL;
    1846             :         memset(newDesc->contentCreationDate, 0, 5);
    1847             :         newDesc->tag = GF_ODF_CC_DATE_TAG;
    1848             :         return (GF_Descriptor *) newDesc;
    1849             : }
    1850             : 
    1851             : 
    1852             : GF_Err gf_odf_del_cc_date(GF_CC_Date *cdd)
    1853             : {
    1854             :         if (!cdd) return GF_BAD_PARAM;
    1855             :         gf_free(cdd);
    1856             :         return GF_OK;
    1857             : }
    1858             : 
    1859             : GF_Err gf_odf_read_cc_date(GF_BitStream *bs, GF_CC_Date *cdd, u32 DescSize)
    1860             : {
    1861             :         u32 nbBytes = 0;
    1862             :         if (!cdd) return GF_BAD_PARAM;
    1863             : 
    1864             :         gf_bs_read_data(bs, cdd->contentCreationDate, DATE_CODING_LEN);
    1865             :         nbBytes += DATE_CODING_LEN;
    1866             :         if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
    1867             :         return GF_OK;
    1868             : }
    1869             : 
    1870             : GF_Err gf_odf_size_cc_date(GF_CC_Date *cdd, u32 *outSize)
    1871             : {
    1872             :         if (!cdd) return GF_BAD_PARAM;
    1873             :         *outSize = DATE_CODING_LEN;
    1874             :         return GF_OK;
    1875             : }
    1876             : 
    1877             : GF_Err gf_odf_write_cc_date(GF_BitStream *bs, GF_CC_Date *cdd)
    1878             : {
    1879             :         u32 size;
    1880             :         GF_Err e;
    1881             :         if (!cdd) return GF_BAD_PARAM;
    1882             : 
    1883             :         e = gf_odf_size_descriptor((GF_Descriptor *)cdd, &size);
    1884             :         if (e) return e;
    1885             :         e = gf_odf_write_base_descriptor(bs, cdd->tag, size);
    1886             :         if (e) return e;
    1887             : 
    1888             :         gf_bs_write_data(bs, cdd->contentCreationDate, DATE_CODING_LEN);
    1889             :         return GF_OK;
    1890             : }
    1891             : 
    1892             : GF_Descriptor *gf_odf_new_cc_name()
    1893             : {
    1894             :         GF_CC_Name *newDesc = (GF_CC_Name *) gf_malloc(sizeof(GF_CC_Name));
    1895             :         if (!newDesc) return NULL;
    1896             : 
    1897             :         newDesc->ContentCreators = gf_list_new();
    1898             :         if (! newDesc->ContentCreators) {
    1899             :                 gf_free(newDesc);
    1900             :                 return NULL;
    1901             :         }
    1902             :         newDesc->tag = GF_ODF_CC_NAME_TAG;
    1903             :         return (GF_Descriptor *) newDesc;
    1904             : }
    1905             : 
    1906             : GF_Err gf_odf_del_cc_name(GF_CC_Name *cnd)
    1907             : {
    1908             :         u32 i;
    1909             :         GF_ContentCreatorInfo *tmp;
    1910             :         if (!cnd) return GF_BAD_PARAM;
    1911             : 
    1912             :         i=0;
    1913             :         while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
    1914             :                 if (tmp->contentCreatorName) gf_free(tmp->contentCreatorName);
    1915             :                 gf_free(tmp);
    1916             :         }
    1917             :         gf_list_del(cnd->ContentCreators);
    1918             :         gf_free(cnd);
    1919             :         return GF_OK;
    1920             : }
    1921             : 
    1922             : GF_Err gf_odf_read_cc_name(GF_BitStream *bs, GF_CC_Name *cnd, u32 DescSize)
    1923             : {
    1924             :         GF_Err e;
    1925             :         u32 i, count, len, nbBytes = 0;
    1926             :         if (!cnd) return GF_BAD_PARAM;
    1927             : 
    1928             :         count = gf_bs_read_int(bs, 8);
    1929             :         nbBytes += 1;
    1930             :         for (i = 0; i< count; i++) {
    1931             :                 GF_ContentCreatorInfo *tmp = (GF_ContentCreatorInfo*)gf_malloc(sizeof(GF_ContentCreatorInfo));
    1932             :                 if (! tmp) return GF_OUT_OF_MEM;
    1933             :                 memset(tmp , 0, sizeof(GF_ContentCreatorInfo));
    1934             :                 tmp->langCode = gf_bs_read_int(bs, 24);
    1935             :                 tmp->isUTF8 = gf_bs_read_int(bs, 1);
    1936             :                 /*aligned = */gf_bs_read_int(bs, 7);
    1937             :                 nbBytes += 4;
    1938             : 
    1939             :                 e = OD_ReadUTF8String(bs, & tmp->contentCreatorName, tmp->isUTF8, &len);
    1940             :                 if (e) {
    1941             :                         gf_free(tmp);
    1942             :                         return e;
    1943             :                 }
    1944             :                 nbBytes += len;
    1945             :                 e = gf_list_add(cnd->ContentCreators, tmp);
    1946             :                 if (e) return e;
    1947             :         }
    1948             :         if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
    1949             :         return GF_OK;
    1950             : }
    1951             : 
    1952             : GF_Err gf_odf_size_cc_name(GF_CC_Name *cnd, u32 *outSize)
    1953             : {
    1954             :         u32 i;
    1955             :         GF_ContentCreatorInfo *tmp;
    1956             :         if (!cnd) return GF_BAD_PARAM;
    1957             : 
    1958             :         *outSize = 1;
    1959             :         i=0;
    1960             :         while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
    1961             :                 *outSize += 4 + OD_SizeUTF8String(tmp->contentCreatorName, tmp->isUTF8);
    1962             :         }
    1963             :         return GF_OK;
    1964             : }
    1965             : 
    1966             : GF_Err gf_odf_write_cc_name(GF_BitStream *bs, GF_CC_Name *cnd)
    1967             : {
    1968             :         GF_Err e;
    1969             :         GF_ContentCreatorInfo *tmp;
    1970             :         u32 i, size;
    1971             :         if (!cnd) return GF_BAD_PARAM;
    1972             : 
    1973             :         e = gf_odf_size_descriptor((GF_Descriptor *)cnd, &size);
    1974             :         if (e) return e;
    1975             :         e = gf_odf_write_base_descriptor(bs, cnd->tag, size);
    1976             :         if (e) return e;
    1977             :         gf_bs_write_int(bs, gf_list_count(cnd->ContentCreators), 8);
    1978             : 
    1979             :         i=0;
    1980             :         while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) {
    1981             :                 gf_bs_write_int(bs, tmp->langCode, 24);
    1982             :                 gf_bs_write_int(bs, tmp->isUTF8, 1);
    1983             :                 gf_bs_write_int(bs, 0, 7);              //aligned
    1984             :                 OD_WriteUTF8String(bs, tmp->contentCreatorName, tmp->isUTF8);
    1985             :         }
    1986             :         return GF_OK;
    1987             : }
    1988             : 
    1989             : 
    1990             : GF_Descriptor *gf_odf_new_ci()
    1991             : {
    1992             :         GF_CIDesc *newDesc = (GF_CIDesc *) gf_malloc(sizeof(GF_CIDesc));
    1993             :         if (!newDesc) return NULL;
    1994             : 
    1995             :         newDesc->compatibility = 0;
    1996             :         newDesc->contentIdentifier = NULL;
    1997             :         newDesc->tag = GF_ODF_CI_TAG;
    1998             :         newDesc->contentIdentifierFlag = 0;
    1999             :         newDesc->contentIdentifierType = 0;
    2000             :         newDesc->contentType = 0;
    2001             :         newDesc->contentTypeFlag = 0;
    2002             :         newDesc->protectedContent = 0;
    2003             :         return (GF_Descriptor *) newDesc;
    2004             : }
    2005             : 
    2006             : 
    2007             : GF_Err gf_odf_del_ci(GF_CIDesc *cid)
    2008             : {
    2009             :         if (!cid) return GF_BAD_PARAM;
    2010             : 
    2011             :         if (cid->contentIdentifier) gf_free(cid->contentIdentifier);
    2012             :         gf_free(cid);
    2013             :         return GF_OK;
    2014             : }
    2015             : 
    2016             : 
    2017             : GF_Err gf_odf_read_ci(GF_BitStream *bs, GF_CIDesc *cid, u32 DescSize)
    2018             : {
    2019             :         u32 nbBytes = 0;
    2020             :         if (! cid) return GF_BAD_PARAM;
    2021             : 
    2022             :         cid->compatibility = gf_bs_read_int(bs, 2);  //MUST BE NULL
    2023             :         if (cid->compatibility) return GF_ODF_INVALID_DESCRIPTOR;
    2024             : 
    2025             :         cid->contentTypeFlag = gf_bs_read_int(bs, 1);
    2026             :         cid->contentIdentifierFlag = gf_bs_read_int(bs, 1);
    2027             :         cid->protectedContent = gf_bs_read_int(bs, 1);
    2028             :         /*reserved = */gf_bs_read_int(bs, 3);
    2029             :         nbBytes += 1;
    2030             : 
    2031             :         if (cid->contentTypeFlag) {
    2032             :                 cid->contentType = gf_bs_read_int(bs, 8);
    2033             :                 nbBytes += 1;
    2034             :         }
    2035             :         if (cid->contentIdentifierFlag) {
    2036             :                 cid->contentIdentifierType = gf_bs_read_int(bs, 8);
    2037             :                 if (DescSize < (u32) 2 + cid->contentTypeFlag) return GF_ODF_INVALID_DESCRIPTOR;
    2038             :                 cid->contentIdentifier = (char*)gf_malloc(DescSize - 2 - cid->contentTypeFlag);
    2039             :                 if (! cid->contentIdentifier) return GF_OUT_OF_MEM;
    2040             : 
    2041             :                 gf_bs_read_data(bs, cid->contentIdentifier, DescSize - 2 - cid->contentTypeFlag);
    2042             :                 nbBytes += DescSize - 1 - cid->contentTypeFlag;
    2043             :         }
    2044             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    2045             :         return GF_OK;
    2046             : }
    2047             : 
    2048             : GF_Err gf_odf_size_ci(GF_CIDesc *cid, u32 *outSize)
    2049             : {
    2050             :         if (! cid) return GF_BAD_PARAM;
    2051             : 
    2052             :         *outSize = 1;
    2053             :         if (cid->contentTypeFlag) *outSize += 1;
    2054             : 
    2055             :         if (cid->contentIdentifierFlag)
    2056             :                 *outSize += (u32) strlen((const char*)cid->contentIdentifier) - 1 - cid->contentTypeFlag;
    2057             :         return GF_OK;
    2058             : }
    2059             : 
    2060             : GF_Err gf_odf_write_ci(GF_BitStream *bs, GF_CIDesc *cid)
    2061             : {
    2062             :         GF_Err e;
    2063             :         u32 size;
    2064             :         if (! cid) return GF_BAD_PARAM;
    2065             : 
    2066             :         e = gf_odf_size_descriptor((GF_Descriptor *)cid, &size);
    2067             :         if (e) return e;
    2068             :         e = gf_odf_write_base_descriptor(bs, cid->tag, size);
    2069             :         if (e) return e;
    2070             : 
    2071             :         gf_bs_write_int(bs, cid->compatibility, 2);
    2072             :         gf_bs_write_int(bs, cid->contentTypeFlag, 1);
    2073             :         gf_bs_write_int(bs, cid->contentIdentifierFlag, 1);
    2074             :         gf_bs_write_int(bs, cid->protectedContent, 1);
    2075             :         gf_bs_write_int(bs, 7, 3);              //reserved 0b111 = 7
    2076             : 
    2077             :         if (cid->contentTypeFlag) {
    2078             :                 gf_bs_write_int(bs, cid->contentType, 8);
    2079             :         }
    2080             : 
    2081             :         if (cid->contentIdentifierFlag) {
    2082             :                 gf_bs_write_int(bs, cid->contentIdentifierType, 8);
    2083             :                 gf_bs_write_data(bs, cid->contentIdentifier, size - 2 - cid->contentTypeFlag);
    2084             :         }
    2085             :         return GF_OK;
    2086             : }
    2087             : 
    2088             : GF_Descriptor *gf_odf_new_exp_text()
    2089             : {
    2090             :         GF_ExpandedTextual *newDesc = (GF_ExpandedTextual *) gf_malloc(sizeof(GF_ExpandedTextual));
    2091             :         if (!newDesc) return NULL;
    2092             : 
    2093             :         newDesc->itemDescriptionList = gf_list_new();
    2094             :         if (! newDesc->itemDescriptionList) {
    2095             :                 gf_free(newDesc);
    2096             :                 return NULL;
    2097             :         }
    2098             :         newDesc->itemTextList = gf_list_new();
    2099             :         if (! newDesc->itemTextList) {
    2100             :                 gf_free(newDesc->itemDescriptionList);
    2101             :                 gf_free(newDesc);
    2102             :                 return NULL;
    2103             :         }
    2104             :         newDesc->isUTF8 = 0;
    2105             :         newDesc->langCode = 0;
    2106             :         newDesc->NonItemText = NULL;
    2107             :         newDesc->tag = GF_ODF_TEXT_TAG;
    2108             :         return (GF_Descriptor *) newDesc;
    2109             : }
    2110             : 
    2111             : GF_Err gf_odf_del_exp_text(GF_ExpandedTextual *etd)
    2112             : {
    2113             :         if (!etd) return GF_BAD_PARAM;
    2114             : 
    2115             :         while (gf_list_count(etd->itemDescriptionList)) {
    2116             :                 GF_ETD_ItemText *tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemDescriptionList, 0);
    2117             :                 if (tmp) {
    2118             :                         if (tmp->text) gf_free(tmp->text);
    2119             :                         gf_free(tmp);
    2120             :                 }
    2121             :                 gf_list_rem(etd->itemDescriptionList, 0);
    2122             :         }
    2123             :         gf_list_del(etd->itemDescriptionList);
    2124             : 
    2125             :         while (gf_list_count(etd->itemTextList)) {
    2126             :                 GF_ETD_ItemText *tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, 0);
    2127             :                 if (tmp) {
    2128             :                         if (tmp->text) gf_free(tmp->text);
    2129             :                         gf_free(tmp);
    2130             :                 }
    2131             :                 gf_list_rem(etd->itemTextList, 0);
    2132             :         }
    2133             :         gf_list_del(etd->itemTextList);
    2134             : 
    2135             :         if (etd->NonItemText) gf_free(etd->NonItemText);
    2136             :         gf_free(etd);
    2137             :         return GF_OK;
    2138             : }
    2139             : 
    2140             : GF_Err gf_odf_read_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd, u32 DescSize)
    2141             : {
    2142             :         GF_Err e;
    2143             :         u32 nbBytes = 0;
    2144             :         u32 i, len, nonLen, count;
    2145             :         if (!etd) return GF_BAD_PARAM;
    2146             : 
    2147             :         etd->langCode = gf_bs_read_int(bs, 24);
    2148             :         etd->isUTF8 = gf_bs_read_int(bs, 1);
    2149             :         /*aligned = */gf_bs_read_int(bs, 7);
    2150             :         count = gf_bs_read_int(bs, 8);
    2151             :         nbBytes += 5;
    2152             : 
    2153             :         for (i = 0; i< count; i++) {
    2154             :                 //description
    2155             :                 GF_ETD_ItemText *description, *Text;
    2156             :                 description = (GF_ETD_ItemText*)gf_malloc(sizeof(GF_ETD_ItemText));
    2157             :                 if (! description) return GF_OUT_OF_MEM;
    2158             :                 description->text = NULL;
    2159             :                 e = OD_ReadUTF8String(bs, & description->text, etd->isUTF8, &len);
    2160             :                 if (e) {
    2161             :                         gf_free(description);
    2162             :                         return e;
    2163             :                 }
    2164             :                 e = gf_list_add(etd->itemDescriptionList, description);
    2165             :                 if (e) return e;
    2166             :                 nbBytes += len;
    2167             : 
    2168             :                 //text
    2169             :                 Text = (GF_ETD_ItemText*)gf_malloc(sizeof(GF_ETD_ItemText));
    2170             :                 if (! Text) return GF_OUT_OF_MEM;
    2171             :                 Text->text = NULL;
    2172             :                 e = OD_ReadUTF8String(bs, & Text->text, etd->isUTF8, &len);
    2173             :                 if (e) return e;
    2174             :                 e = gf_list_add(etd->itemTextList, Text);
    2175             :                 if (e) return e;
    2176             :                 nbBytes += len;
    2177             :         }
    2178             :         len = gf_bs_read_int(bs, 8);
    2179             :         nbBytes += 1;
    2180             :         nonLen = 0;
    2181             :         while (len == 255) {
    2182             :                 nonLen += len;
    2183             :                 len = gf_bs_read_int(bs, 8);
    2184             :                 nbBytes += 1;
    2185             :         }
    2186             :         nonLen += len;
    2187             :         if (nonLen) {
    2188             :                 //here we have no choice but do the job ourselves
    2189             :                 //because the length is not encoded on 8 bits
    2190             :                 etd->NonItemText = (char *) gf_malloc(sizeof(char) * (1+nonLen) * (etd->isUTF8 ? 1 : 2));
    2191             :                 if (! etd->NonItemText) return GF_OUT_OF_MEM;
    2192             :                 gf_bs_read_data(bs, etd->NonItemText, nonLen * (etd->isUTF8 ? 1 : 2));
    2193             :                 nbBytes += nonLen * (etd->isUTF8 ? 1 : 2);
    2194             :         }
    2195             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    2196             :         return GF_OK;
    2197             : }
    2198             : 
    2199             : 
    2200             : GF_Err gf_odf_size_exp_text(GF_ExpandedTextual *etd, u32 *outSize)
    2201             : {
    2202             :         u32 i, len, nonLen, lentmp, count;
    2203             :         if (!etd) return GF_BAD_PARAM;
    2204             : 
    2205             :         *outSize = 5;
    2206             :         if (gf_list_count(etd->itemDescriptionList) != gf_list_count(etd->itemTextList)) return GF_ODF_INVALID_DESCRIPTOR;
    2207             : 
    2208             :         count = gf_list_count(etd->itemDescriptionList);
    2209             :         for (i=0; i<count; i++) {
    2210             :                 GF_ETD_ItemText *tmp = (GF_ETD_ItemText *)gf_list_get(etd->itemDescriptionList, i);
    2211             :                 *outSize += OD_SizeUTF8String(tmp->text, etd->isUTF8);
    2212             :                 tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, i);
    2213             :                 *outSize += OD_SizeUTF8String(tmp->text, etd->isUTF8);
    2214             :         }
    2215             :         *outSize += 1;
    2216             :         if (etd->NonItemText) {
    2217             :                 if (etd->isUTF8) {
    2218             :                         nonLen = (u32) strlen((const char*)etd->NonItemText);
    2219             :                 } else {
    2220             :                         nonLen = (u32) gf_utf8_wcslen((const unsigned short*)etd->NonItemText);
    2221             :                 }
    2222             :         } else {
    2223             :                 nonLen = 0;
    2224             :         }
    2225             :         len = 255;
    2226             :         lentmp = nonLen;
    2227             :         if (lentmp < 255) {
    2228             :                 len = lentmp;
    2229             :         }
    2230             :         while (len == 255) {
    2231             :                 *outSize += 1;
    2232             :                 lentmp -= 255;
    2233             :                 if (lentmp < 255) {
    2234             :                         len = lentmp;
    2235             :                 }
    2236             :         }
    2237             :         *outSize += nonLen * (etd->isUTF8 ? 1 : 2);
    2238             :         return GF_OK;
    2239             : }
    2240             : 
    2241             : GF_Err gf_odf_write_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd)
    2242             : {
    2243             :         GF_Err e;
    2244             :         u32 size, i, len, nonLen, lentmp, count;
    2245             :         if (!etd) return GF_BAD_PARAM;
    2246             : 
    2247             :         if (gf_list_count(etd->itemDescriptionList) != gf_list_count(etd->itemTextList)) return GF_ODF_INVALID_DESCRIPTOR;
    2248             : 
    2249             :         e = gf_odf_size_descriptor((GF_Descriptor *)etd, &size);
    2250             :         if (e) return e;
    2251             :         e = gf_odf_write_base_descriptor(bs, etd->tag, size);
    2252             :         if (e) return e;
    2253             : 
    2254             :         gf_bs_write_int(bs, etd->langCode, 24);
    2255             :         gf_bs_write_int(bs, etd->isUTF8, 1);
    2256             :         gf_bs_write_int(bs, 0, 7);              //aligned
    2257             :         gf_bs_write_int(bs, gf_list_count(etd->itemDescriptionList), 8);
    2258             : 
    2259             :         count = gf_list_count(etd->itemDescriptionList);
    2260             :         for (i=0; i<count; i++) {
    2261             :                 GF_ETD_ItemText *tmp = (GF_ETD_ItemText *)gf_list_get(etd->itemDescriptionList, i);
    2262             :                 OD_WriteUTF8String(bs, tmp->text, etd->isUTF8);
    2263             :                 tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, i);
    2264             :                 OD_WriteUTF8String(bs, tmp->text, etd->isUTF8);
    2265             :         }
    2266             :         if (etd->NonItemText) {
    2267             :                 if (etd->isUTF8) {
    2268             :                         nonLen = (u32) strlen((const char*)etd->NonItemText);
    2269             :                 } else {
    2270             :                         nonLen = (u32) gf_utf8_wcslen((const unsigned short*)etd->NonItemText);
    2271             :                 }
    2272             :         } else {
    2273             :                 nonLen = 0;
    2274             :         }
    2275             :         lentmp = nonLen;
    2276             :         len = lentmp < 255 ? lentmp : 255;
    2277             :         while (len == 255) {
    2278             :                 gf_bs_write_int(bs, len, 8);
    2279             :                 lentmp -= len;
    2280             :                 len = lentmp < 255 ? lentmp : 255;
    2281             :         }
    2282             :         gf_bs_write_int(bs, len, 8);
    2283             :         gf_bs_write_data(bs, etd->NonItemText, nonLen * (etd->isUTF8 ? 1 : 2));
    2284             :         return GF_OK;
    2285             : }
    2286             : 
    2287             : GF_Descriptor *gf_odf_new_pl_ext()
    2288             : {
    2289             :         GF_PLExt *newDesc = (GF_PLExt *) gf_malloc(sizeof(GF_PLExt));
    2290             :         if (!newDesc) return NULL;
    2291             :         newDesc->AudioProfileLevelIndication = 0;
    2292             :         newDesc->GraphicsProfileLevelIndication = 0;
    2293             :         newDesc->MPEGJProfileLevelIndication = 0;
    2294             :         newDesc->ODProfileLevelIndication = 0;
    2295             :         newDesc->profileLevelIndicationIndex = 0;
    2296             :         newDesc->SceneProfileLevelIndication = 0;
    2297             :         newDesc->VisualProfileLevelIndication = 0;
    2298             :         newDesc->tag = GF_ODF_EXT_PL_TAG;
    2299             :         return (GF_Descriptor *) newDesc;
    2300             : }
    2301             : 
    2302             : GF_Err gf_odf_del_pl_ext(GF_PLExt *pld)
    2303             : {
    2304             :         if (!pld) return GF_BAD_PARAM;
    2305             : 
    2306             :         gf_free(pld);
    2307             :         return GF_OK;
    2308             : }
    2309             : 
    2310             : GF_Err gf_odf_read_pl_ext(GF_BitStream *bs, GF_PLExt *pld, u32 DescSize)
    2311             : {
    2312             :         u32 nbBytes = 0;
    2313             :         if (!pld) return GF_BAD_PARAM;
    2314             : 
    2315             :         pld->profileLevelIndicationIndex = gf_bs_read_int(bs, 8);
    2316             :         pld->ODProfileLevelIndication = gf_bs_read_int(bs, 8);
    2317             :         pld->SceneProfileLevelIndication = gf_bs_read_int(bs, 8);
    2318             :         pld->AudioProfileLevelIndication = gf_bs_read_int(bs, 8);
    2319             :         pld->VisualProfileLevelIndication = gf_bs_read_int(bs, 8);
    2320             :         pld->GraphicsProfileLevelIndication = gf_bs_read_int(bs, 8);
    2321             :         pld->MPEGJProfileLevelIndication = gf_bs_read_int(bs, 8);
    2322             : 
    2323             :         nbBytes += 7;
    2324             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    2325             :         return GF_OK;
    2326             : }
    2327             : 
    2328             : GF_Err gf_odf_size_pl_ext(GF_PLExt *pld, u32 *outSize)
    2329             : {
    2330             :         if (!pld) return GF_BAD_PARAM;
    2331             : 
    2332             :         *outSize = 7;
    2333             :         return GF_OK;
    2334             : }
    2335             : 
    2336             : GF_Err gf_odf_write_pl_ext(GF_BitStream *bs, GF_PLExt *pld)
    2337             : {
    2338             :         GF_Err e;
    2339             :         u32 size;
    2340             :         if (!pld) return GF_BAD_PARAM;
    2341             : 
    2342             :         e = gf_odf_size_descriptor((GF_Descriptor *)pld, &size);
    2343             :         if (e) return e;
    2344             :         e = gf_odf_write_base_descriptor(bs, pld->tag, size);
    2345             :         if (e) return e;
    2346             : 
    2347             :         gf_bs_write_int(bs, pld->profileLevelIndicationIndex, 8);
    2348             :         gf_bs_write_int(bs, pld->ODProfileLevelIndication, 8);
    2349             :         gf_bs_write_int(bs, pld->SceneProfileLevelIndication, 8);
    2350             :         gf_bs_write_int(bs, pld->AudioProfileLevelIndication, 8);
    2351             :         gf_bs_write_int(bs, pld->VisualProfileLevelIndication, 8);
    2352             :         gf_bs_write_int(bs, pld->GraphicsProfileLevelIndication, 8);
    2353             :         gf_bs_write_int(bs, pld->MPEGJProfileLevelIndication, 8);
    2354             :         return GF_OK;
    2355             : }
    2356             : 
    2357             : GF_Descriptor *gf_odf_new_ipi_ptr()
    2358             : {
    2359             :         GF_IPIPtr *newDesc = (GF_IPIPtr *) gf_malloc(sizeof(GF_IPIPtr));
    2360             :         if (!newDesc) return NULL;
    2361             :         newDesc->IPI_ES_Id = 0;
    2362             :         newDesc->tag = GF_ODF_IPI_PTR_TAG;
    2363             :         return (GF_Descriptor *) newDesc;
    2364             : }
    2365             : 
    2366             : GF_Err gf_odf_del_ipi_ptr(GF_IPIPtr *ipid)
    2367             : {
    2368             :         if (!ipid) return GF_BAD_PARAM;
    2369             :         gf_free(ipid);
    2370             :         return GF_OK;
    2371             : }
    2372             : 
    2373             : GF_Err gf_odf_read_ipi_ptr(GF_BitStream *bs, GF_IPIPtr *ipid, u32 DescSize)
    2374             : {
    2375             :         u32 nbBytes = 0;
    2376             :         if (! ipid) return GF_BAD_PARAM;
    2377             : 
    2378             :         ipid->IPI_ES_Id = gf_bs_read_int(bs, 16);
    2379             :         nbBytes += 2;
    2380             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    2381             :         return GF_OK;
    2382             : }
    2383             : 
    2384             : GF_Err gf_odf_size_ipi_ptr(GF_IPIPtr *ipid, u32 *outSize)
    2385             : {
    2386             :         if (! ipid) return GF_BAD_PARAM;
    2387             :         *outSize = 2;
    2388             :         return GF_OK;
    2389             : }
    2390             : 
    2391             : GF_Err gf_odf_write_ipi_ptr(GF_BitStream *bs, GF_IPIPtr *ipid)
    2392             : {
    2393             :         GF_Err e;
    2394             :         u32 size;
    2395             :         if (! ipid) return GF_BAD_PARAM;
    2396             :         e = gf_odf_size_descriptor((GF_Descriptor *)ipid, &size);
    2397             :         if (e) return e;
    2398             :         e = gf_odf_write_base_descriptor(bs, ipid->tag, size);
    2399             :         if (e) return e;
    2400             :         gf_bs_write_int(bs, ipid->IPI_ES_Id, 16);
    2401             :         return GF_OK;
    2402             : }
    2403             : 
    2404             : GF_Descriptor *gf_odf_new_ipmp()
    2405             : {
    2406             :         GF_IPMP_Descriptor *newDesc;
    2407             :         GF_SAFEALLOC(newDesc, GF_IPMP_Descriptor);
    2408             :         if (!newDesc) return NULL;
    2409             : 
    2410             :         newDesc->ipmpx_data = gf_list_new();
    2411             :         newDesc->tag = GF_ODF_IPMP_TAG;
    2412             :         return (GF_Descriptor *) newDesc;
    2413             : }
    2414             : GF_Err gf_odf_del_ipmp(GF_IPMP_Descriptor *ipmp)
    2415             : {
    2416             :         if (!ipmp) return GF_BAD_PARAM;
    2417             :         if (ipmp->opaque_data) gf_free(ipmp->opaque_data);
    2418             : #ifndef GPAC_MINIMAL_ODF
    2419             :         /*TODO DELETE IPMPX*/
    2420             :         while (gf_list_count(ipmp->ipmpx_data)) {
    2421             :                 GF_IPMPX_Data *p = (GF_IPMPX_Data *)gf_list_get(ipmp->ipmpx_data, 0);
    2422             :                 gf_list_rem(ipmp->ipmpx_data, 0);
    2423             :                 gf_ipmpx_data_del(p);
    2424             :         }
    2425             : #endif
    2426             :         gf_list_del(ipmp->ipmpx_data);
    2427             :         gf_free(ipmp);
    2428             :         return GF_OK;
    2429             : }
    2430             : 
    2431             : GF_Err gf_odf_read_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp, u32 DescSize)
    2432             : {
    2433             :         u32 size;
    2434             :         u64 nbBytes = 0;
    2435             :         if (!ipmp) return GF_BAD_PARAM;
    2436             : 
    2437             :         ipmp->IPMP_DescriptorID = gf_bs_read_int(bs, 8);
    2438             :         ipmp->IPMPS_Type = gf_bs_read_int(bs, 16);
    2439             :         nbBytes += 3;
    2440             :         if (DescSize<3) return GF_ODF_INVALID_DESCRIPTOR;
    2441             : 
    2442             :         size = DescSize - 3;
    2443             : 
    2444             :         /*IPMPX escape*/
    2445             :         if ((ipmp->IPMP_DescriptorID==0xFF) && (ipmp->IPMPS_Type==0xFFFF)) {
    2446             :                 ipmp->IPMP_DescriptorIDEx = gf_bs_read_int(bs, 16);
    2447             :                 if (gf_bs_available(bs) < 16) return GF_ODF_INVALID_DESCRIPTOR;
    2448             :                 gf_bs_read_data(bs, (char*)ipmp->IPMP_ToolID, 16);
    2449             :                 ipmp->control_point = gf_bs_read_int(bs, 8);
    2450             :                 nbBytes += 19;
    2451             :                 if (ipmp->control_point) {
    2452             :                         ipmp->cp_sequence_code = gf_bs_read_int(bs, 8);
    2453             :                         nbBytes += 1;
    2454             :                 }
    2455             :                 while (nbBytes<DescSize) {
    2456             :                         u64 pos;
    2457             :                         GF_Err e;
    2458             :                         GF_IPMPX_Data *p;
    2459             :                         pos = gf_bs_get_position(bs);
    2460             :                         e = gf_ipmpx_data_parse(bs, &p);
    2461             :                         if (e) return e;
    2462             :                         gf_list_add(ipmp->ipmpx_data, p);
    2463             :                         nbBytes += gf_bs_get_position(bs) - pos;
    2464             :                 }
    2465             :         }
    2466             :         /*URL*/
    2467             :         else if (! ipmp->IPMPS_Type) {
    2468             :                 ipmp->opaque_data = (char*)gf_malloc(size + 1);
    2469             :                 if (! ipmp->opaque_data) return GF_OUT_OF_MEM;
    2470             :                 gf_bs_read_data(bs, ipmp->opaque_data, size);
    2471             :                 nbBytes += size;
    2472             :                 ipmp->opaque_data[size] = 0;
    2473             :                 ipmp->opaque_data_size = size;
    2474             : 
    2475             :         }
    2476             :         /*data*/
    2477             :         else {
    2478             :                 ipmp->opaque_data_size = size;
    2479             :                 ipmp->opaque_data = (char*)gf_malloc(size);
    2480             :                 if (! ipmp->opaque_data) return GF_OUT_OF_MEM;
    2481             :                 gf_bs_read_data(bs, ipmp->opaque_data, size);
    2482             :                 nbBytes += size;
    2483             :         }
    2484             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    2485             :         return GF_OK;
    2486             : }
    2487             : 
    2488             : GF_Err gf_odf_size_ipmp(GF_IPMP_Descriptor *ipmp, u32 *outSize)
    2489             : {
    2490             :         u32 i, s;
    2491             :         if (!ipmp) return GF_BAD_PARAM;
    2492             : 
    2493             :         *outSize = 3;
    2494             :         /*IPMPX escape*/
    2495             :         if ((ipmp->IPMP_DescriptorID==0xFF) && (ipmp->IPMPS_Type==0xFFFF)) {
    2496             :                 GF_IPMPX_Data *p;
    2497             :                 *outSize += 19;
    2498             :                 if (ipmp->control_point) *outSize += 1;
    2499             :                 s = 0;
    2500             :                 i=0;
    2501             :                 while ((p = (GF_IPMPX_Data *)gf_list_enum(ipmp->ipmpx_data, &i))) {
    2502             :                         s += gf_ipmpx_data_full_size(p);
    2503             :                 }
    2504             :                 (*outSize) += s;
    2505             :         }
    2506             :         else if (! ipmp->IPMPS_Type) {
    2507             :                 if (!ipmp->opaque_data) return GF_ODF_INVALID_DESCRIPTOR;
    2508             :                 *outSize += (u32) strlen(ipmp->opaque_data);
    2509             :         } else {
    2510             :                 *outSize += ipmp->opaque_data_size;
    2511             :         }
    2512             :         return GF_OK;
    2513             : }
    2514             : 
    2515             : GF_Err gf_odf_write_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp)
    2516             : {
    2517             :         GF_Err e;
    2518             :         u32 size, i;
    2519             :         if (!ipmp) return GF_BAD_PARAM;
    2520             : 
    2521             :         e = gf_odf_size_descriptor((GF_Descriptor *)ipmp, &size);
    2522             :         if (e) return e;
    2523             :         e = gf_odf_write_base_descriptor(bs, ipmp->tag, size);
    2524             :         if (e) return e;
    2525             :         gf_bs_write_int(bs, ipmp->IPMP_DescriptorID, 8);
    2526             :         gf_bs_write_int(bs, ipmp->IPMPS_Type, 16);
    2527             : 
    2528             :         if ((ipmp->IPMP_DescriptorID==0xFF) && (ipmp->IPMPS_Type==0xFFFF)) {
    2529             :                 GF_IPMPX_Data *p;
    2530             :                 gf_bs_write_int(bs, ipmp->IPMP_DescriptorIDEx, 16);
    2531             :                 gf_bs_write_data(bs, (char*)ipmp->IPMP_ToolID, 16);
    2532             :                 gf_bs_write_int(bs, ipmp->control_point, 8);
    2533             :                 if (ipmp->control_point) gf_bs_write_int(bs, ipmp->cp_sequence_code, 8);
    2534             : 
    2535             :                 i=0;
    2536             :                 while ((p = (GF_IPMPX_Data *) gf_list_enum(ipmp->ipmpx_data, &i))) {
    2537             :                         gf_ipmpx_data_write(bs, p);
    2538             :                 }
    2539             :         }
    2540             :         else if (!ipmp->IPMPS_Type) {
    2541             :                 if (!ipmp->opaque_data) return GF_ODF_INVALID_DESCRIPTOR;
    2542             :                 gf_bs_write_data(bs, ipmp->opaque_data, (u32) strlen(ipmp->opaque_data));
    2543             :         } else {
    2544             :                 gf_bs_write_data(bs, ipmp->opaque_data, ipmp->opaque_data_size);
    2545             :         }
    2546             :         return GF_OK;
    2547             : }
    2548             : 
    2549             : GF_Descriptor *gf_odf_new_ipmp_ptr()
    2550             : {
    2551             :         GF_IPMPPtr *newDesc;
    2552             :         GF_SAFEALLOC(newDesc, GF_IPMPPtr);
    2553             :         if (!newDesc) return NULL;
    2554             :         newDesc->tag = GF_ODF_IPMP_PTR_TAG;
    2555             :         return (GF_Descriptor *) newDesc;
    2556             : }
    2557             : GF_Err gf_odf_del_ipmp_ptr(GF_IPMPPtr *ipmpd)
    2558             : {
    2559             :         if (!ipmpd) return GF_BAD_PARAM;
    2560             :         gf_free(ipmpd);
    2561             :         return GF_OK;
    2562             : }
    2563             : 
    2564             : GF_Err gf_odf_read_ipmp_ptr(GF_BitStream *bs, GF_IPMPPtr *ipmpd, u32 DescSize)
    2565             : {
    2566             :         u32 nbBytes = 0;
    2567             :         if (! ipmpd) return GF_BAD_PARAM;
    2568             :         ipmpd->IPMP_DescriptorID = gf_bs_read_int(bs, 8);
    2569             :         nbBytes += 1;
    2570             :         if (ipmpd->IPMP_DescriptorID == 0xFF) {
    2571             :                 ipmpd->IPMP_DescriptorIDEx = gf_bs_read_int(bs, 16);
    2572             :                 ipmpd->IPMP_ES_ID = gf_bs_read_int(bs, 16);
    2573             :                 nbBytes += 4;
    2574             :         }
    2575             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    2576             :         return GF_OK;
    2577             : }
    2578             : GF_Err gf_odf_size_ipmp_ptr(GF_IPMPPtr *ipmpd, u32 *outSize)
    2579             : {
    2580             :         if (! ipmpd) return GF_BAD_PARAM;
    2581             :         *outSize = 1;
    2582             :         if (ipmpd->IPMP_DescriptorID == 0xFF) *outSize += 4;
    2583             :         return GF_OK;
    2584             : }
    2585             : GF_Err gf_odf_write_ipmp_ptr(GF_BitStream *bs, GF_IPMPPtr *ipmpd)
    2586             : {
    2587             :         GF_Err e;
    2588             :         u32 size;
    2589             :         if (! ipmpd) return GF_BAD_PARAM;
    2590             : 
    2591             :         e = gf_odf_size_descriptor((GF_Descriptor *)ipmpd, &size);
    2592             :         if (e) return e;
    2593             :         e = gf_odf_write_base_descriptor(bs, ipmpd->tag, size);
    2594             :         if (e) return e;
    2595             :         gf_bs_write_int(bs, ipmpd->IPMP_DescriptorID, 8);
    2596             :         if (ipmpd->IPMP_DescriptorID == 0xFF) {
    2597             :                 gf_bs_write_int(bs, ipmpd->IPMP_DescriptorIDEx, 16);
    2598             :                 gf_bs_write_int(bs, ipmpd->IPMP_ES_ID, 16);
    2599             :         }
    2600             :         return GF_OK;
    2601             : }
    2602             : 
    2603             : GF_Descriptor *gf_odf_new_kw()
    2604             : {
    2605             :         GF_KeyWord *newDesc = (GF_KeyWord *) gf_malloc(sizeof(GF_KeyWord));
    2606             :         if (!newDesc) return NULL;
    2607             : 
    2608             :         newDesc->keyWordsList = gf_list_new();
    2609             :         if (! newDesc->keyWordsList) {
    2610             :                 gf_free(newDesc);
    2611             :                 return NULL;
    2612             :         }
    2613             :         newDesc->isUTF8 = 0;
    2614             :         newDesc->languageCode = 0;
    2615             :         newDesc->tag = GF_ODF_KW_TAG;
    2616             :         return (GF_Descriptor *) newDesc;
    2617             : }
    2618             : 
    2619             : GF_Err gf_odf_del_kw(GF_KeyWord *kwd)
    2620             : {
    2621             :         if (!kwd) return GF_BAD_PARAM;
    2622             : 
    2623             :         while (gf_list_count(kwd->keyWordsList)) {
    2624             :                 GF_KeyWordItem *tmp = (GF_KeyWordItem*)gf_list_get(kwd->keyWordsList, 0);
    2625             :                 if (tmp) {
    2626             :                         if (tmp->keyWord) gf_free(tmp->keyWord);
    2627             :                         tmp->keyWord = NULL;
    2628             :                         gf_list_rem(kwd->keyWordsList, 0);
    2629             :                         gf_free(tmp);
    2630             :                 }
    2631             :         }
    2632             :         gf_list_del(kwd->keyWordsList);
    2633             :         gf_free(kwd);
    2634             :         return GF_OK;
    2635             : }
    2636             : 
    2637             : GF_Err gf_odf_read_kw(GF_BitStream *bs, GF_KeyWord *kwd, u32 DescSize)
    2638             : {
    2639             :         GF_Err e;
    2640             :         u32 nbBytes = 0, i, kwcount, len;
    2641             :         if (!kwd) return GF_BAD_PARAM;
    2642             : 
    2643             :         kwd->languageCode = gf_bs_read_int(bs, 24);
    2644             :         kwd->isUTF8 = gf_bs_read_int(bs, 1);
    2645             :         /*aligned = */gf_bs_read_int(bs, 7);
    2646             :         kwcount = gf_bs_read_int(bs, 8);
    2647             :         nbBytes += 5;
    2648             : 
    2649             :         for (i = 0 ; i < kwcount; i++) {
    2650             :                 GF_KeyWordItem *tmp = (GF_KeyWordItem*)gf_malloc(sizeof(GF_KeyWordItem));
    2651             :                 if (! tmp) return GF_OUT_OF_MEM;
    2652             :                 e = OD_ReadUTF8String(bs, & tmp->keyWord, kwd->isUTF8, &len);
    2653             :                 if (e) {
    2654             :                         if (tmp->keyWord) gf_free(tmp->keyWord);
    2655             :                         gf_free(tmp);
    2656             :                         return e;
    2657             :                 }
    2658             :                 nbBytes += len;
    2659             :                 if (nbBytes > DescSize) {
    2660             :                         gf_free(tmp->keyWord);
    2661             :                         gf_free(tmp);
    2662             :                         return GF_ODF_INVALID_DESCRIPTOR;
    2663             :                 }
    2664             :                 e = gf_list_add(kwd->keyWordsList, tmp);
    2665             :                 if (e) {
    2666             :                         if (tmp) gf_free(tmp);
    2667             :                         return e;
    2668             :                 }
    2669             :         }
    2670             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    2671             :         return GF_OK;
    2672             : }
    2673             : 
    2674             : 
    2675             : GF_Err gf_odf_size_kw(GF_KeyWord *kwd, u32 *outSize)
    2676             : {
    2677             :         u32 i;
    2678             :         GF_KeyWordItem *tmp;
    2679             :         if (!kwd) return GF_BAD_PARAM;
    2680             : 
    2681             :         *outSize = 5;
    2682             :         i=0;
    2683             :         while ((tmp = (GF_KeyWordItem *)gf_list_enum(kwd->keyWordsList, &i))) {
    2684             :                 *outSize += OD_SizeUTF8String(tmp->keyWord, kwd->isUTF8);
    2685             :         }
    2686             :         return GF_OK;
    2687             : }
    2688             : GF_Err gf_odf_write_kw(GF_BitStream *bs, GF_KeyWord *kwd)
    2689             : {
    2690             :         GF_Err e;
    2691             :         u32 size, i;
    2692             :         GF_KeyWordItem *tmp;
    2693             :         if (!kwd) return GF_BAD_PARAM;
    2694             : 
    2695             :         e = gf_odf_size_descriptor((GF_Descriptor *)kwd, &size);
    2696             :         if (e) return e;
    2697             :         e = gf_odf_write_base_descriptor(bs, kwd->tag, size);
    2698             :         if (e) return e;
    2699             : 
    2700             :         gf_bs_write_int(bs, kwd->languageCode, 24);
    2701             :         gf_bs_write_int(bs, kwd->isUTF8, 1);
    2702             :         gf_bs_write_int(bs, 0, 7);              //aligned(8)
    2703             :         gf_bs_write_int(bs, gf_list_count(kwd->keyWordsList), 8);
    2704             : 
    2705             :         i=0;
    2706             :         while ((tmp = (GF_KeyWordItem *)gf_list_enum(kwd->keyWordsList, &i))) {
    2707             :                 OD_WriteUTF8String(bs, tmp->keyWord, kwd->isUTF8);
    2708             :         }
    2709             :         return GF_OK;
    2710             : }
    2711             : 
    2712             : GF_Descriptor *gf_odf_new_oci_date()
    2713             : {
    2714             :         GF_OCI_Data *newDesc = (GF_OCI_Data *) gf_malloc(sizeof(GF_OCI_Data));
    2715             :         if (!newDesc) return NULL;
    2716             :         memset(newDesc->OCICreationDate, 0, 5);
    2717             :         newDesc->tag = GF_ODF_OCI_DATE_TAG;
    2718             :         return (GF_Descriptor *) newDesc;
    2719             : }
    2720             : 
    2721             : GF_Err gf_odf_del_oci_date(GF_OCI_Data *ocd)
    2722             : {
    2723             :         if (!ocd) return GF_BAD_PARAM;
    2724             :         gf_free(ocd);
    2725             :         return GF_OK;
    2726             : }
    2727             : 
    2728             : GF_Err gf_odf_read_oci_date(GF_BitStream *bs, GF_OCI_Data *ocd, u32 DescSize)
    2729             : {
    2730             :         u32 nbBytes = 0;
    2731             :         if (!ocd) return GF_BAD_PARAM;
    2732             : 
    2733             :         gf_bs_read_data(bs, ocd->OCICreationDate, DATE_CODING_LEN);
    2734             :         nbBytes += DATE_CODING_LEN;
    2735             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    2736             :         return GF_OK;
    2737             : }
    2738             : 
    2739             : GF_Err gf_odf_size_oci_date(GF_OCI_Data *ocd, u32 *outSize)
    2740             : {
    2741             :         if (!ocd) return GF_BAD_PARAM;
    2742             :         *outSize = DATE_CODING_LEN;
    2743             :         return GF_OK;
    2744             : }
    2745             : 
    2746             : GF_Err gf_odf_write_oci_date(GF_BitStream *bs, GF_OCI_Data *ocd)
    2747             : {
    2748             :         GF_Err e;
    2749             :         u32 size;
    2750             :         if (!ocd) return GF_BAD_PARAM;
    2751             : 
    2752             :         e = gf_odf_size_descriptor((GF_Descriptor *)ocd, &size);
    2753             :         if (e) return e;
    2754             :         e = gf_odf_write_base_descriptor(bs, ocd->tag, size);
    2755             :         if (e) return e;
    2756             :         gf_bs_write_data(bs, ocd->OCICreationDate, DATE_CODING_LEN);
    2757             :         return GF_OK;
    2758             : }
    2759             : 
    2760             : GF_Descriptor *gf_odf_new_oci_name()
    2761             : {
    2762             :         GF_OCICreators *newDesc = (GF_OCICreators *) gf_malloc(sizeof(GF_OCICreators));
    2763             :         if (!newDesc) return NULL;
    2764             : 
    2765             :         newDesc->OCICreators = gf_list_new();
    2766             :         if (! newDesc->OCICreators) {
    2767             :                 gf_free(newDesc);
    2768             :                 return NULL;
    2769             :         }
    2770             :         newDesc->tag = GF_ODF_OCI_NAME_TAG;
    2771             :         return (GF_Descriptor *) newDesc;
    2772             : }
    2773             : GF_Err gf_odf_del_oci_name(GF_OCICreators *ocn)
    2774             : {
    2775             :         u32 i;
    2776             :         GF_OCICreator_item *tmp;
    2777             :         if (!ocn) return GF_BAD_PARAM;
    2778             : 
    2779             :         i=0;
    2780             :         while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
    2781             :                 if (tmp->OCICreatorName) gf_free(tmp->OCICreatorName);
    2782             :                 gf_free(tmp);
    2783             :         }
    2784             :         gf_list_del(ocn->OCICreators);
    2785             :         gf_free(ocn);
    2786             :         return GF_OK;
    2787             : }
    2788             : 
    2789             : GF_Err gf_odf_read_oci_name(GF_BitStream *bs, GF_OCICreators *ocn, u32 DescSize)
    2790             : {
    2791             :         GF_Err e;
    2792             :         u32 nbBytes = 0;
    2793             :         u32 i, count, len;
    2794             :         if (!ocn) return GF_BAD_PARAM;
    2795             : 
    2796             :         count = gf_bs_read_int(bs, 8);
    2797             :         nbBytes += 1;
    2798             :         for (i = 0; i< count; i++) {
    2799             :                 GF_OCICreator_item *tmp = (GF_OCICreator_item*)gf_malloc(sizeof(GF_OCICreator_item));
    2800             :                 if (! tmp) return GF_OUT_OF_MEM;
    2801             :                 tmp->langCode = gf_bs_read_int(bs, 24);
    2802             :                 tmp->isUTF8 = gf_bs_read_int(bs, 1);
    2803             :                 /*aligned = */gf_bs_read_int(bs, 7);
    2804             :                 nbBytes += 4;
    2805             :                 e = OD_ReadUTF8String(bs, & tmp->OCICreatorName, tmp->isUTF8, &len);
    2806             :                 if (e) {
    2807             :                         gf_free(tmp);
    2808             :                         return e;
    2809             :                 }
    2810             :                 nbBytes += len;
    2811             :                 e = gf_list_add(ocn->OCICreators, tmp);
    2812             :                 if (e) return e;
    2813             :         }
    2814             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    2815             :         return GF_OK;
    2816             : }
    2817             : 
    2818             : GF_Err gf_odf_size_oci_name(GF_OCICreators *ocn, u32 *outSize)
    2819             : {
    2820             :         u32 i;
    2821             :         GF_OCICreator_item *tmp;
    2822             :         if (!ocn) return GF_BAD_PARAM;
    2823             : 
    2824             :         *outSize = 1;
    2825             :         i=0;
    2826             :         while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
    2827             :                 *outSize += 4 + OD_SizeUTF8String(tmp->OCICreatorName, tmp->isUTF8);
    2828             :         }
    2829             :         return GF_OK;
    2830             : }
    2831             : 
    2832             : GF_Err gf_odf_write_oci_name(GF_BitStream *bs, GF_OCICreators *ocn)
    2833             : {
    2834             :         GF_Err e;
    2835             :         u32 size;
    2836             :         u32 i;
    2837             :         GF_OCICreator_item *tmp;
    2838             :         if (!ocn) return GF_BAD_PARAM;
    2839             : 
    2840             :         e = gf_odf_size_descriptor((GF_Descriptor *)ocn, &size);
    2841             :         if (e) return e;
    2842             :         e = gf_odf_write_base_descriptor(bs, ocn->tag, size);
    2843             :         if (e) return e;
    2844             :         gf_bs_write_int(bs, gf_list_count(ocn->OCICreators), 8);
    2845             : 
    2846             :         i=0;
    2847             :         while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) {
    2848             :                 gf_bs_write_int(bs, tmp->langCode, 24);
    2849             :                 gf_bs_write_int(bs, tmp->isUTF8, 1);
    2850             :                 gf_bs_write_int(bs, 0, 7);              //aligned
    2851             :                 gf_bs_write_int(bs, (u32) strlen(tmp->OCICreatorName) , 8);
    2852             :                 OD_WriteUTF8String(bs, tmp->OCICreatorName, tmp->isUTF8);
    2853             :         }
    2854             :         return GF_OK;
    2855             : }
    2856             : 
    2857             : 
    2858             : GF_Descriptor *gf_odf_new_pl_idx()
    2859             : {
    2860             :         GF_PL_IDX *newDesc = (GF_PL_IDX *) gf_malloc(sizeof(GF_PL_IDX));
    2861             :         if (!newDesc) return NULL;
    2862             :         newDesc->profileLevelIndicationIndex = 0;
    2863             :         newDesc->tag = GF_ODF_PL_IDX_TAG;
    2864             :         return (GF_Descriptor *) newDesc;
    2865             : }
    2866             : 
    2867             : GF_Err gf_odf_del_pl_idx(GF_PL_IDX *plid)
    2868             : {
    2869             :         if (!plid) return GF_BAD_PARAM;
    2870             :         gf_free(plid);
    2871             :         return GF_OK;
    2872             : }
    2873             : 
    2874             : GF_Err gf_odf_read_pl_idx(GF_BitStream *bs, GF_PL_IDX *plid, u32 DescSize)
    2875             : {
    2876             :         u32 nbBytes = 0;
    2877             :         if (!plid) return GF_BAD_PARAM;
    2878             : 
    2879             :         plid->profileLevelIndicationIndex = gf_bs_read_int(bs, 8);
    2880             :         nbBytes += 1;
    2881             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    2882             :         return GF_OK;
    2883             : }
    2884             : GF_Err gf_odf_size_pl_idx(GF_PL_IDX *plid, u32 *outSize)
    2885             : {
    2886             :         if (!plid) return GF_BAD_PARAM;
    2887             :         *outSize = 1;
    2888             :         return GF_OK;
    2889             : }
    2890             : GF_Err gf_odf_write_pl_idx(GF_BitStream *bs, GF_PL_IDX *plid)
    2891             : {
    2892             :         GF_Err e;
    2893             :         u32 size;
    2894             :         if (!plid) return GF_BAD_PARAM;
    2895             :         e = gf_odf_size_descriptor((GF_Descriptor *)plid, &size);
    2896             :         if (e) return e;
    2897             :         e = gf_odf_write_base_descriptor(bs, plid->tag, size);
    2898             :         if (e) return e;
    2899             :         gf_bs_write_int(bs, plid->profileLevelIndicationIndex, 8);
    2900             :         return GF_OK;
    2901             : }
    2902             : 
    2903             : 
    2904             : GF_Descriptor *gf_odf_new_rating()
    2905             : {
    2906             :         GF_Rating *newDesc = (GF_Rating *) gf_malloc(sizeof(GF_Rating));
    2907             :         if (!newDesc) return NULL;
    2908             : 
    2909             :         newDesc->infoLength = 0;
    2910             :         newDesc->ratingInfo = NULL;
    2911             :         newDesc->ratingCriteria = 0;
    2912             :         newDesc->ratingEntity = 0;
    2913             :         newDesc->tag = GF_ODF_RATING_TAG;
    2914             :         return (GF_Descriptor *) newDesc;
    2915             : }
    2916             : 
    2917             : GF_Err gf_odf_del_rating(GF_Rating *rd)
    2918             : {
    2919             :         if (!rd) return GF_BAD_PARAM;
    2920             : 
    2921             :         if (rd->ratingInfo) gf_free(rd->ratingInfo);
    2922             :         gf_free(rd);
    2923             :         return GF_OK;
    2924             : }
    2925             : 
    2926             : GF_Err gf_odf_read_rating(GF_BitStream *bs, GF_Rating *rd, u32 DescSize)
    2927             : {
    2928             :         u32 nbBytes = 0;
    2929             :         if (!rd) return GF_BAD_PARAM;
    2930             : 
    2931             :         rd->ratingEntity = gf_bs_read_int(bs, 32);
    2932             :         rd->ratingCriteria = gf_bs_read_int(bs, 16);
    2933             :         if (DescSize<6) return GF_ODF_INVALID_DESCRIPTOR;
    2934             :         rd->infoLength = DescSize - 6;
    2935             :         nbBytes += 6;
    2936             : 
    2937             :         rd->ratingInfo = (char*)gf_malloc(rd->infoLength);
    2938             :         if (! rd->ratingInfo) return GF_OUT_OF_MEM;
    2939             :         gf_bs_read_data(bs, rd->ratingInfo, rd->infoLength);
    2940             :         nbBytes += rd->infoLength;
    2941             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    2942             :         return GF_OK;
    2943             : }
    2944             : 
    2945             : GF_Err gf_odf_size_rating(GF_Rating *rd, u32 *outSize)
    2946             : {
    2947             :         if (!rd) return GF_BAD_PARAM;
    2948             : 
    2949             :         *outSize = 6 + rd->infoLength;
    2950             :         return GF_OK;
    2951             : }
    2952             : 
    2953             : GF_Err gf_odf_write_rating(GF_BitStream *bs, GF_Rating *rd)
    2954             : {
    2955             :         GF_Err e;
    2956             :         u32 size;
    2957             :         if (!rd) return GF_BAD_PARAM;
    2958             :         e = gf_odf_size_descriptor((GF_Descriptor *)rd, &size);
    2959             :         if (e) return e;
    2960             :         e = gf_odf_write_base_descriptor(bs, rd->tag, size);
    2961             :         if (e) return e;
    2962             :         gf_bs_write_int(bs, rd->ratingEntity, 32);
    2963             :         gf_bs_write_int(bs, rd->ratingCriteria, 16);
    2964             :         gf_bs_write_data(bs, rd->ratingInfo, rd->infoLength);
    2965             :         return GF_OK;
    2966             : }
    2967             : 
    2968             : 
    2969             : GF_Descriptor *gf_odf_new_reg()
    2970             : {
    2971             :         GF_Registration *newDesc = (GF_Registration *) gf_malloc(sizeof(GF_Registration));
    2972             :         if (!newDesc) return NULL;
    2973             :         newDesc->additionalIdentificationInfo = NULL;
    2974             :         newDesc->dataLength = 0;
    2975             :         newDesc->formatIdentifier = 0;
    2976             :         newDesc->tag = GF_ODF_REG_TAG;
    2977             :         return (GF_Descriptor *) newDesc;
    2978             : }
    2979             : 
    2980             : GF_Err gf_odf_del_reg(GF_Registration *reg)
    2981             : {
    2982             :         if (!reg) return GF_BAD_PARAM;
    2983             : 
    2984             :         if (reg->additionalIdentificationInfo) gf_free(reg->additionalIdentificationInfo);
    2985             :         gf_free(reg);
    2986             :         return GF_OK;
    2987             : }
    2988             : 
    2989             : GF_Err gf_odf_read_reg(GF_BitStream *bs, GF_Registration *reg, u32 DescSize)
    2990             : {
    2991             :         u32 nbBytes = 0;
    2992             :         if (!reg) return GF_BAD_PARAM;
    2993             : 
    2994             :         reg->formatIdentifier = gf_bs_read_int(bs, 32);
    2995             :         if (DescSize<4) return GF_ODF_INVALID_DESCRIPTOR;
    2996             :         reg->dataLength = DescSize - 4;
    2997             :         reg->additionalIdentificationInfo = (char*)gf_malloc(reg->dataLength);
    2998             :         if (! reg->additionalIdentificationInfo) return GF_OUT_OF_MEM;
    2999             :         gf_bs_read_data(bs, reg->additionalIdentificationInfo, reg->dataLength);
    3000             :         nbBytes += reg->dataLength + 4;
    3001             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    3002             :         return GF_OK;
    3003             : }
    3004             : 
    3005             : 
    3006             : GF_Err gf_odf_size_reg(GF_Registration *reg, u32 *outSize)
    3007             : {
    3008             :         if (!reg) return GF_BAD_PARAM;
    3009             : 
    3010             :         *outSize = 4 + reg->dataLength;
    3011             :         return GF_OK;
    3012             : }
    3013             : 
    3014             : GF_Err gf_odf_write_reg(GF_BitStream *bs, GF_Registration *reg)
    3015             : {
    3016             :         GF_Err e;
    3017             :         u32 size;
    3018             :         if (!reg) return GF_BAD_PARAM;
    3019             : 
    3020             :         e = gf_odf_size_descriptor((GF_Descriptor *)reg, &size);
    3021             :         if (e) return e;
    3022             :         e = gf_odf_write_base_descriptor(bs, reg->tag, size);
    3023             :         if (e) return e;
    3024             : 
    3025             :         gf_bs_write_int(bs, reg->formatIdentifier, 32);
    3026             :         gf_bs_write_data(bs, reg->additionalIdentificationInfo, reg->dataLength);
    3027             :         return GF_OK;
    3028             : }
    3029             : 
    3030             : GF_Descriptor *gf_odf_new_short_text()
    3031             : {
    3032             :         GF_ShortTextual *newDesc = (GF_ShortTextual *) gf_malloc(sizeof(GF_ShortTextual));
    3033             :         if (!newDesc) return NULL;
    3034             : 
    3035             :         newDesc->eventName = NULL;
    3036             :         newDesc->eventText = NULL;
    3037             :         newDesc->isUTF8 = 0;
    3038             :         newDesc->langCode = 0;
    3039             :         newDesc->tag = GF_ODF_SHORT_TEXT_TAG;
    3040             :         return (GF_Descriptor *) newDesc;
    3041             : }
    3042             : 
    3043             : GF_Err gf_odf_del_short_text(GF_ShortTextual *std)
    3044             : {
    3045             :         if (!std) return GF_BAD_PARAM;
    3046             : 
    3047             :         if (std->eventName) gf_free(std->eventName);
    3048             :         if (std->eventText) gf_free(std->eventText);
    3049             :         gf_free(std);
    3050             :         return GF_OK;
    3051             : }
    3052             : 
    3053             : GF_Err gf_odf_read_short_text(GF_BitStream *bs, GF_ShortTextual *std, u32 DescSize)
    3054             : {
    3055             :         GF_Err e;
    3056             :         u32 nbBytes = 0, len;
    3057             :         if (!std) return GF_BAD_PARAM;
    3058             : 
    3059             :         std->langCode = gf_bs_read_int(bs, 24);
    3060             :         std->isUTF8 = gf_bs_read_int(bs, 1);
    3061             :         /*aligned = */gf_bs_read_int(bs, 7);
    3062             :         nbBytes += 4;
    3063             : 
    3064             :         e = OD_ReadUTF8String(bs, & std->eventName, std->isUTF8, &len);
    3065             :         if (e) return e;
    3066             :         nbBytes += len;
    3067             :         e = OD_ReadUTF8String(bs, & std->eventText, std->isUTF8, &len);
    3068             :         if (e) return e;
    3069             :         nbBytes += len;
    3070             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    3071             :         return GF_OK;
    3072             : }
    3073             : 
    3074             : GF_Err gf_odf_size_short_text(GF_ShortTextual *std, u32 *outSize)
    3075             : {
    3076             :         if (!std) return GF_BAD_PARAM;
    3077             :         *outSize = 4;
    3078             :         *outSize += OD_SizeUTF8String(std->eventName, std->isUTF8) + OD_SizeUTF8String(std->eventText, std->isUTF8);
    3079             :         return GF_OK;
    3080             : }
    3081             : 
    3082             : GF_Err gf_odf_write_short_text(GF_BitStream *bs, GF_ShortTextual *std)
    3083             : {
    3084             :         GF_Err e;
    3085             :         u32 size;
    3086             :         if (!std) return GF_BAD_PARAM;
    3087             : 
    3088             :         e = gf_odf_size_descriptor((GF_Descriptor *)std, &size);
    3089             :         if (e) return e;
    3090             :         e = gf_odf_write_base_descriptor(bs, std->tag, size);
    3091             :         if (e) return e;
    3092             :         gf_bs_write_int(bs, std->langCode, 24);
    3093             :         gf_bs_write_int(bs, std->isUTF8, 1);
    3094             :         gf_bs_write_int(bs, 0, 7);
    3095             :         OD_WriteUTF8String(bs, std->eventName, std->isUTF8);
    3096             :         OD_WriteUTF8String(bs, std->eventText, std->isUTF8);
    3097             :         return GF_OK;
    3098             : }
    3099             : 
    3100             : GF_Descriptor *gf_odf_new_smpte_camera()
    3101             : {
    3102             :         GF_SMPTECamera *newDesc = (GF_SMPTECamera *) gf_malloc(sizeof(GF_SMPTECamera));
    3103             :         if (!newDesc) return NULL;
    3104             : 
    3105             :         newDesc->ParamList = gf_list_new();
    3106             :         if (! newDesc->ParamList) {
    3107             :                 gf_free(newDesc);
    3108             :                 return NULL;
    3109             :         }
    3110             :         newDesc->cameraID = 0;
    3111             :         newDesc->tag = GF_ODF_SMPTE_TAG;
    3112             :         return (GF_Descriptor *) newDesc;
    3113             : }
    3114             : 
    3115             : GF_Err gf_odf_del_smpte_camera(GF_SMPTECamera *cpd)
    3116             : {
    3117             :         u32 i;
    3118             :         GF_SmpteParam *tmp;
    3119             :         if (!cpd) return GF_BAD_PARAM;
    3120             : 
    3121             :         i=0;
    3122             :         while ((tmp = (GF_SmpteParam *)gf_list_enum(cpd->ParamList, &i))) {
    3123             :                 gf_free(tmp);
    3124             :         }
    3125             :         gf_list_del(cpd->ParamList);
    3126             :         gf_free(cpd);
    3127             :         return GF_OK;
    3128             : }
    3129             : GF_Err gf_odf_read_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd, u32 DescSize)
    3130             : {
    3131             :         GF_Err e;
    3132             :         u32 nbBytes = 0, i, count;
    3133             :         if (!cpd) return GF_BAD_PARAM;
    3134             : 
    3135             :         cpd->cameraID = gf_bs_read_int(bs, 8);
    3136             :         count = gf_bs_read_int(bs, 8);
    3137             :         nbBytes += 2;
    3138             : 
    3139             :         for (i=0; i< count ; i++) {
    3140             :                 GF_SmpteParam *tmp = (GF_SmpteParam*)gf_malloc(sizeof(GF_SmpteParam));
    3141             :                 if (! tmp) return GF_OUT_OF_MEM;
    3142             :                 tmp->paramID = gf_bs_read_int(bs, 8);
    3143             :                 tmp->param = gf_bs_read_int(bs, 32);
    3144             :                 nbBytes += 5;
    3145             :                 e = gf_list_add(cpd->ParamList, tmp);
    3146             :                 if (e) return e;
    3147             :         }
    3148             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    3149             :         return GF_OK;
    3150             : }
    3151             : 
    3152             : GF_Err gf_odf_size_smpte_camera(GF_SMPTECamera *cpd, u32 *outSize)
    3153             : {
    3154             :         if (!cpd) return GF_BAD_PARAM;
    3155             :         *outSize = 2 + 5 * gf_list_count(cpd->ParamList);
    3156             :         return GF_OK;
    3157             : }
    3158             : 
    3159             : GF_Err gf_odf_write_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd)
    3160             : {
    3161             :         GF_Err e;
    3162             :         GF_SmpteParam *tmp;
    3163             :         u32 size, i;
    3164             :         if (!cpd) return GF_BAD_PARAM;
    3165             : 
    3166             :         e = gf_odf_size_descriptor((GF_Descriptor *)cpd, &size);
    3167             :         if (e) return e;
    3168             :         e = gf_odf_write_base_descriptor(bs, cpd->tag, size);
    3169             :         if (e) return e;
    3170             :         gf_bs_write_int(bs, cpd->cameraID, 8);
    3171             :         gf_bs_write_int(bs, gf_list_count(cpd->ParamList), 8);
    3172             : 
    3173             :         i=0;
    3174             :         while ((tmp = (GF_SmpteParam *)gf_list_enum(cpd->ParamList, &i))) {
    3175             :                 gf_bs_write_int(bs, tmp->paramID, 8);
    3176             :                 gf_bs_write_int(bs, tmp->param, 32);
    3177             :         }
    3178             :         return GF_OK;
    3179             : }
    3180             : 
    3181             : GF_Descriptor *gf_odf_new_sup_cid()
    3182             : {
    3183             :         GF_SCIDesc *newDesc = (GF_SCIDesc *) gf_malloc(sizeof(GF_SCIDesc));
    3184             :         if (!newDesc) return NULL;
    3185             :         newDesc->supplContentIdentifierTitle = NULL;
    3186             :         newDesc->supplContentIdentifierValue  =NULL;
    3187             :         newDesc->languageCode = 0;
    3188             :         newDesc->tag = GF_ODF_SCI_TAG;
    3189             :         return (GF_Descriptor *) newDesc;
    3190             : }
    3191             : 
    3192             : GF_Err gf_odf_del_sup_cid(GF_SCIDesc *scid)
    3193             : {
    3194             :         if (!scid) return GF_BAD_PARAM;
    3195             : 
    3196             :         if (scid->supplContentIdentifierTitle) gf_free(scid->supplContentIdentifierTitle);
    3197             :         if (scid->supplContentIdentifierValue) gf_free(scid->supplContentIdentifierValue);
    3198             :         gf_free(scid);
    3199             :         return GF_OK;
    3200             : }
    3201             : 
    3202             : GF_Err gf_odf_read_sup_cid(GF_BitStream *bs, GF_SCIDesc *scid, u32 DescSize)
    3203             : {
    3204             :         GF_Err e;
    3205             :         u32 nbBytes = 0, len;
    3206             :         if (! scid) return GF_BAD_PARAM;
    3207             : 
    3208             :         scid->languageCode = gf_bs_read_int(bs, 24);
    3209             :         nbBytes += 3;
    3210             :         e = OD_ReadUTF8String(bs, & scid->supplContentIdentifierTitle, GF_TRUE, &len);
    3211             :         if (e) return e;
    3212             :         nbBytes += len;
    3213             :         e = OD_ReadUTF8String(bs, & scid->supplContentIdentifierValue, GF_TRUE, &len);
    3214             :         if (e) return e;
    3215             :         nbBytes += len;
    3216             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    3217             :         return GF_OK;
    3218             : }
    3219             : 
    3220             : 
    3221             : GF_Err gf_odf_size_sup_cid(GF_SCIDesc *scid, u32 *outSize)
    3222             : {
    3223             :         if (! scid) return GF_BAD_PARAM;
    3224             :         *outSize = 3 + OD_SizeUTF8String(scid->supplContentIdentifierTitle, GF_TRUE) + OD_SizeUTF8String(scid->supplContentIdentifierValue, GF_TRUE);
    3225             :         return GF_OK;
    3226             : }
    3227             : GF_Err gf_odf_write_sup_cid(GF_BitStream *bs, GF_SCIDesc *scid)
    3228             : {
    3229             :         GF_Err e;
    3230             :         u32 size;
    3231             :         if (! scid) return GF_BAD_PARAM;
    3232             :         e = gf_odf_size_descriptor((GF_Descriptor *)scid, &size);
    3233             :         if (e) return e;
    3234             :         e = gf_odf_write_base_descriptor(bs, scid->tag, size);
    3235             :         if (e) return e;
    3236             :         gf_bs_write_int(bs, scid->languageCode, 24);
    3237             :         OD_WriteUTF8String(bs, scid->supplContentIdentifierTitle, GF_TRUE);
    3238             :         OD_WriteUTF8String(bs, scid->supplContentIdentifierValue, GF_TRUE);
    3239             :         return GF_OK;
    3240             : }
    3241             : 
    3242             : 
    3243             : /*IPMPX stuff*/
    3244             : GF_Descriptor *gf_odf_new_ipmp_tool_list()
    3245             : {
    3246             :         GF_IPMP_ToolList*newDesc = (GF_IPMP_ToolList*) gf_malloc(sizeof(GF_IPMP_ToolList));
    3247             :         if (!newDesc) return NULL;
    3248             :         newDesc->ipmp_tools = gf_list_new();
    3249             :         newDesc->tag = GF_ODF_IPMP_TL_TAG;
    3250             :         return (GF_Descriptor *) newDesc;
    3251             : }
    3252             : 
    3253             : GF_Err gf_odf_del_ipmp_tool_list(GF_IPMP_ToolList *ipmptl)
    3254             : {
    3255             :         if (!ipmptl) return GF_BAD_PARAM;
    3256             : 
    3257             :         while (gf_list_count(ipmptl->ipmp_tools)) {
    3258             :                 GF_Descriptor *t = (GF_Descriptor *) gf_list_get(ipmptl->ipmp_tools, 0);
    3259             :                 gf_list_rem(ipmptl->ipmp_tools, 0);
    3260             :                 gf_odf_delete_descriptor(t);
    3261             :         }
    3262             :         gf_list_del(ipmptl->ipmp_tools);
    3263             :         gf_free(ipmptl);
    3264             :         return GF_OK;
    3265             : }
    3266             : 
    3267             : GF_Err gf_odf_read_ipmp_tool_list(GF_BitStream *bs, GF_IPMP_ToolList *ipmptl, u32 DescSize)
    3268             : {
    3269             :         GF_Err e;
    3270             :         u32 tmpSize;
    3271             :         u32 nbBytes = 0;
    3272             :         if (! ipmptl) return GF_BAD_PARAM;
    3273             : 
    3274             :         while (nbBytes < DescSize) {
    3275             :                 GF_Descriptor *tmp = NULL;
    3276             :                 e = gf_odf_parse_descriptor(bs, &tmp, &tmpSize);
    3277             :                 if (e) return e;
    3278             :                 if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
    3279             :                 e = gf_list_add(ipmptl->ipmp_tools, tmp);
    3280             :                 if (e) return e;
    3281             :                 nbBytes += tmpSize + gf_odf_size_field_size(tmpSize);
    3282             :         }
    3283             :         if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    3284             :         return GF_OK;
    3285             : }
    3286             : 
    3287             : 
    3288             : GF_Err gf_odf_size_ipmp_tool_list(GF_IPMP_ToolList *ipmptl, u32 *outSize)
    3289             : {
    3290             :         if (!ipmptl) return GF_BAD_PARAM;
    3291             :         *outSize = 0;
    3292             :         return gf_odf_size_descriptor_list(ipmptl->ipmp_tools, outSize);
    3293             : }
    3294             : 
    3295             : GF_Err gf_odf_write_ipmp_tool_list(GF_BitStream *bs, GF_IPMP_ToolList *ipmptl)
    3296             : {
    3297             :         GF_Err e;
    3298             :         u32 size;
    3299             :         if (!ipmptl) return GF_BAD_PARAM;
    3300             :         e = gf_odf_size_descriptor((GF_Descriptor *)ipmptl, &size);
    3301             :         if (e) return e;
    3302             :         e = gf_odf_write_base_descriptor(bs, ipmptl->tag, size);
    3303             :         if (e) return e;
    3304             :         return gf_odf_write_descriptor_list(bs, ipmptl->ipmp_tools);
    3305             : }
    3306             : 
    3307             : GF_Descriptor *gf_odf_new_ipmp_tool()
    3308             : {
    3309             :         GF_IPMP_Tool *newDesc = (GF_IPMP_Tool*) gf_malloc(sizeof(GF_IPMP_Tool));
    3310             :         if (!newDesc) return NULL;
    3311             :         memset(newDesc, 0, sizeof(GF_IPMP_Tool));
    3312             :         newDesc->tag = GF_ODF_IPMP_TL_TAG;
    3313             :         return (GF_Descriptor *) newDesc;
    3314             : }
    3315             : 
    3316             : GF_Err gf_odf_del_ipmp_tool(GF_IPMP_Tool *ipmpt)
    3317             : {
    3318             :         if (!ipmpt) return GF_BAD_PARAM;
    3319             :         if (ipmpt->tool_url) gf_free(ipmpt->tool_url);
    3320             :         gf_free(ipmpt);
    3321             :         return GF_OK;
    3322             : }
    3323             : 
    3324             : GF_Err gf_odf_read_ipmp_tool(GF_BitStream *bs, GF_IPMP_Tool *ipmpt, u32 DescSize)
    3325             : {
    3326             :         Bool is_alt, is_param;
    3327             :         u32 nbBytes = 0;
    3328             :         if (! ipmpt) return GF_BAD_PARAM;
    3329             :         gf_bs_read_data(bs, (char*) ipmpt->IPMP_ToolID, 16);
    3330             :         is_alt = (Bool)gf_bs_read_int(bs, 1);
    3331             :         is_param = (Bool)gf_bs_read_int(bs, 1);
    3332             :         gf_bs_read_int(bs, 6);
    3333             :         nbBytes = 17;
    3334             : 
    3335             :         if (is_alt) {
    3336             :                 u32 i;
    3337             :                 ipmpt->num_alternate = gf_bs_read_int(bs, 8);
    3338             :                 nbBytes += 1;
    3339             :                 for (i=0; i<ipmpt->num_alternate; i++) {
    3340             :                         if (nbBytes + 16 > DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    3341             :                         gf_bs_read_data(bs, (char*)ipmpt->specificToolID[i], 16);
    3342             :                         nbBytes += 16;
    3343             :                 }
    3344             :         }
    3345             :         if (nbBytes>DescSize) return GF_ODF_INVALID_DESCRIPTOR;
    3346             : 
    3347             :         if (is_param) { }
    3348             : 
    3349             :         if (nbBytes<DescSize) {
    3350             :                 u32 s;
    3351             :                 nbBytes += gf_ipmpx_array_size(bs, &s);
    3352             :                 if (s>0xFFFFFF) return GF_ODF_INVALID_DESCRIPTOR;
    3353             : 
    3354             :                 if (s) {
    3355             :                         ipmpt->tool_url = (char*)gf_malloc(sizeof(char)*(s+1));
    3356             :                         gf_bs_read_data(bs, ipmpt->tool_url, s);
    3357             :                         ipmpt->tool_url[s] = 0;
    3358             :                         nbBytes += s;
    3359             :                 }
    3360             :         }
    3361             : 
    3362             :         if (nbBytes!=DescSize) return GF_NON_COMPLIANT_BITSTREAM;
    3363             :         return GF_OK;
    3364             : }
    3365             : 
    3366             : 
    3367             : GF_Err gf_odf_size_ipmp_tool(GF_IPMP_Tool *ipmpt, u32 *outSize)
    3368             : {
    3369             :         if (!ipmpt) return GF_BAD_PARAM;
    3370             :         *outSize = 17;
    3371             :         if (ipmpt->num_alternate) *outSize += 1 + 16*ipmpt->num_alternate;
    3372             : 
    3373             :         if (ipmpt->tool_url) {
    3374             :                 u32 s = (u32) strlen(ipmpt->tool_url);
    3375             :                 *outSize += gf_odf_size_field_size(s) - 1 + s;
    3376             :         }
    3377             :         return GF_OK;
    3378             : }
    3379             : 
    3380             : GF_Err gf_odf_write_ipmp_tool(GF_BitStream *bs, GF_IPMP_Tool *ipmpt)
    3381             : {
    3382             :         GF_Err e;
    3383             :         u32 size;
    3384             :         if (!ipmpt) return GF_BAD_PARAM;
    3385             :         e = gf_odf_size_descriptor((GF_Descriptor *)ipmpt, &size);
    3386             :         if (e) return e;
    3387             :         e = gf_odf_write_base_descriptor(bs, ipmpt->tag, size);
    3388             :         if (e) return e;
    3389             : 
    3390             :         gf_bs_write_data(bs, (char*)ipmpt->IPMP_ToolID, 16);
    3391             :         gf_bs_write_int(bs, ipmpt->num_alternate ? 1 : 0, 1);
    3392             :         gf_bs_write_int(bs, 0, 1);
    3393             :         gf_bs_write_int(bs, 0, 6);
    3394             : 
    3395             :         if (ipmpt->num_alternate) {
    3396             :                 u32 i;
    3397             :                 gf_bs_write_int(bs, ipmpt->num_alternate, 8);
    3398             :                 for (i=0; i<ipmpt->num_alternate; i++) gf_bs_write_data(bs, (char*)ipmpt->specificToolID[i], 16);
    3399             :         }
    3400             :         if (ipmpt->tool_url) gf_ipmpx_write_array(bs, ipmpt->tool_url, (u32) strlen(ipmpt->tool_url));
    3401             :         return GF_OK;
    3402             : }
    3403             : 
    3404             : #endif /*GPAC_MINIMAL_ODF*/

Generated by: LCOV version 1.13