| /* | |
| * GPAC - Multimedia Framework C SDK | |
| * | |
| * Authors: Jean Le Feuvre | |
| * Copyright (c) Telecom ParisTech 2000-2023 | |
| * All rights reserved | |
| * | |
| * This file is part of GPAC / ISO Media File Format sub-project | |
| * | |
| * GPAC is free software; you can redistribute it and/or modify | |
| * it under the terms of the GNU Lesser General Public License as published by | |
| * the Free Software Foundation; either version 2, or (at your option) | |
| * any later version. | |
| * | |
| * GPAC is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| * GNU Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; see the file COPYING. If not, write to | |
| * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
| * | |
| */ | |
| #include <gpac/internal/isomedia_dev.h> | |
| #include <gpac/tools.h> | |
| #ifndef GPAC_DISABLE_ISOM | |
| GF_Box *gppc_box_new() | |
| { | |
| //default type is amr but overwritten by box constructor | |
| ISOM_DECL_BOX_ALLOC(GF_3GPPConfigBox, GF_ISOM_BOX_TYPE_DAMR); | |
| return (GF_Box *)tmp; | |
| } | |
| void gppc_box_del(GF_Box *s) | |
| { | |
| GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s; | |
| if (ptr == NULL) return; | |
| gf_free(ptr); | |
| } | |
| GF_Err gppc_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s; | |
| if (ptr == NULL) return GF_BAD_PARAM; | |
| memset(&ptr->cfg, 0, sizeof(GF_3GPConfig)); | |
| ISOM_DECREASE_SIZE(s, 5) | |
| ptr->cfg.vendor = gf_bs_read_u32(bs); | |
| ptr->cfg.decoder_version = gf_bs_read_u8(bs); | |
| switch (ptr->type) { | |
| case GF_ISOM_BOX_TYPE_D263: | |
| ISOM_DECREASE_SIZE(s, 2) | |
| ptr->cfg.H263_level = gf_bs_read_u8(bs); | |
| ptr->cfg.H263_profile = gf_bs_read_u8(bs); | |
| break; | |
| case GF_ISOM_BOX_TYPE_DAMR: | |
| ISOM_DECREASE_SIZE(s, 4) | |
| ptr->cfg.AMR_mode_set = gf_bs_read_u16(bs); | |
| ptr->cfg.AMR_mode_change_period = gf_bs_read_u8(bs); | |
| ptr->cfg.frames_per_sample = gf_bs_read_u8(bs); | |
| break; | |
| case GF_ISOM_BOX_TYPE_DEVC: | |
| case GF_ISOM_BOX_TYPE_DQCP: | |
| case GF_ISOM_BOX_TYPE_DSMV: | |
| ISOM_DECREASE_SIZE(s, 1) | |
| ptr->cfg.frames_per_sample = gf_bs_read_u8(bs); | |
| break; | |
| } | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err gppc_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_u32(bs, ptr->cfg.vendor); | |
| gf_bs_write_u8(bs, ptr->cfg.decoder_version); | |
| switch (ptr->cfg.type) { | |
| case GF_ISOM_SUBTYPE_3GP_H263: | |
| gf_bs_write_u8(bs, ptr->cfg.H263_level); | |
| gf_bs_write_u8(bs, ptr->cfg.H263_profile); | |
| break; | |
| case GF_ISOM_SUBTYPE_3GP_AMR: | |
| case GF_ISOM_SUBTYPE_3GP_AMR_WB: | |
| gf_bs_write_u16(bs, ptr->cfg.AMR_mode_set); | |
| gf_bs_write_u8(bs, ptr->cfg.AMR_mode_change_period); | |
| gf_bs_write_u8(bs, ptr->cfg.frames_per_sample); | |
| break; | |
| case GF_ISOM_SUBTYPE_3GP_EVRC: | |
| case GF_ISOM_SUBTYPE_3GP_QCELP: | |
| case GF_ISOM_SUBTYPE_3GP_SMV: | |
| gf_bs_write_u8(bs, ptr->cfg.frames_per_sample); | |
| break; | |
| } | |
| return GF_OK; | |
| } | |
| GF_Err gppc_box_size(GF_Box *s) | |
| { | |
| GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s; | |
| s->size += 5; | |
| if (!ptr->cfg.type) { | |
| switch (ptr->type) { | |
| case GF_ISOM_BOX_TYPE_D263: | |
| ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_H263; | |
| break; | |
| case GF_ISOM_BOX_TYPE_DAMR: | |
| ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_AMR; | |
| break; | |
| case GF_ISOM_BOX_TYPE_DEVC: | |
| ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_EVRC; | |
| break; | |
| case GF_ISOM_BOX_TYPE_DQCP: | |
| ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_QCELP; | |
| break; | |
| case GF_ISOM_BOX_TYPE_DSMV: | |
| ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_SMV; | |
| break; | |
| } | |
| } | |
| switch (ptr->cfg.type) { | |
| case GF_ISOM_SUBTYPE_3GP_H263: | |
| s->size += 2; | |
| break; | |
| case GF_ISOM_SUBTYPE_3GP_AMR: | |
| case GF_ISOM_SUBTYPE_3GP_AMR_WB: | |
| s->size += 4; | |
| break; | |
| case GF_ISOM_SUBTYPE_3GP_EVRC: | |
| case GF_ISOM_SUBTYPE_3GP_QCELP: | |
| case GF_ISOM_SUBTYPE_3GP_SMV: | |
| s->size += 1; | |
| break; | |
| } | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *ftab_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_FontTableBox, GF_ISOM_BOX_TYPE_FTAB); | |
| return (GF_Box *) tmp; | |
| } | |
| void ftab_box_del(GF_Box *s) | |
| { | |
| GF_FontTableBox *ptr = (GF_FontTableBox *)s; | |
| if (ptr->fonts) { | |
| u32 i; | |
| for (i=0; i<ptr->entry_count; i++) | |
| if (ptr->fonts[i].fontName) gf_free(ptr->fonts[i].fontName); | |
| gf_free(ptr->fonts); | |
| } | |
| gf_free(ptr); | |
| } | |
| GF_Err ftab_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| u32 i; | |
| GF_FontTableBox *ptr = (GF_FontTableBox *)s; | |
| ptr->entry_count = gf_bs_read_u16(bs); | |
| ISOM_DECREASE_SIZE(ptr, 2); | |
| if (ptr->size<ptr->entry_count*3) { | |
| GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Corrupted ftap box, skipping\n")); | |
| ptr->entry_count = 0; | |
| return GF_OK; | |
| } | |
| ptr->fonts = (GF_FontRecord *) gf_malloc(sizeof(GF_FontRecord)*ptr->entry_count); | |
| if (!ptr->fonts) return GF_OUT_OF_MEM; | |
| memset(ptr->fonts, 0, sizeof(GF_FontRecord)*ptr->entry_count); | |
| for (i=0; i<ptr->entry_count; i++) { | |
| u32 len; | |
| ISOM_DECREASE_SIZE(ptr, 3); | |
| ptr->fonts[i].fontID = gf_bs_read_u16(bs); | |
| len = gf_bs_read_u8(bs); | |
| if (len) { | |
| ISOM_DECREASE_SIZE(ptr, len); | |
| ptr->fonts[i].fontName = (char *)gf_malloc(sizeof(char)*(len+1)); | |
| if (!ptr->fonts[i].fontName) return GF_OUT_OF_MEM; | |
| gf_bs_read_data(bs, ptr->fonts[i].fontName, len); | |
| ptr->fonts[i].fontName[len] = 0; | |
| } | |
| } | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err ftab_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| u32 i; | |
| GF_FontTableBox *ptr = (GF_FontTableBox *)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_u16(bs, ptr->entry_count); | |
| for (i=0; i<ptr->entry_count; i++) { | |
| gf_bs_write_u16(bs, ptr->fonts[i].fontID); | |
| if (ptr->fonts[i].fontName) { | |
| u32 len = (u32) strlen(ptr->fonts[i].fontName); | |
| gf_bs_write_u8(bs, len); | |
| gf_bs_write_data(bs, ptr->fonts[i].fontName, len); | |
| } else { | |
| gf_bs_write_u8(bs, 0); | |
| } | |
| } | |
| return GF_OK; | |
| } | |
| GF_Err ftab_box_size(GF_Box *s) | |
| { | |
| u32 i; | |
| GF_FontTableBox *ptr = (GF_FontTableBox *)s; | |
| s->size += 2; | |
| for (i=0; i<ptr->entry_count; i++) { | |
| s->size += 3; | |
| if (ptr->fonts[i].fontName) s->size += strlen(ptr->fonts[i].fontName); | |
| } | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *text_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_TextSampleEntryBox, GF_ISOM_BOX_TYPE_TEXT); | |
| gf_isom_sample_entry_init((GF_SampleEntryBox *)tmp); | |
| return (GF_Box *) tmp; | |
| } | |
| void text_box_del(GF_Box *s) | |
| { | |
| GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; | |
| gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); | |
| if (ptr->textName) | |
| gf_free(ptr->textName); | |
| gf_free(ptr); | |
| } | |
| GF_Box *tx3g_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_Tx3gSampleEntryBox, GF_ISOM_BOX_TYPE_TX3G); | |
| gf_isom_sample_entry_init((GF_SampleEntryBox *)tmp); | |
| return (GF_Box *) tmp; | |
| } | |
| void tx3g_box_del(GF_Box *s) | |
| { | |
| gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); | |
| gf_free(s); | |
| } | |
| u32 gpp_read_rgba(GF_BitStream *bs) | |
| { | |
| u8 r, g, b, a; | |
| u32 col; | |
| r = gf_bs_read_u8(bs); | |
| g = gf_bs_read_u8(bs); | |
| b = gf_bs_read_u8(bs); | |
| a = gf_bs_read_u8(bs); | |
| col = a; | |
| col<<=8; | |
| col |= r; | |
| col<<=8; | |
| col |= g; | |
| col<<=8; | |
| col |= b; | |
| return col; | |
| } | |
| #define GPP_BOX_SIZE 8 | |
| void gpp_read_box(GF_BitStream *bs, GF_BoxRecord *rec) | |
| { | |
| rec->top = gf_bs_read_u16(bs); | |
| rec->left = gf_bs_read_u16(bs); | |
| rec->bottom = gf_bs_read_u16(bs); | |
| rec->right = gf_bs_read_u16(bs); | |
| } | |
| #define GPP_STYLE_SIZE 12 | |
| void gpp_read_style(GF_BitStream *bs, GF_StyleRecord *rec) | |
| { | |
| rec->startCharOffset = gf_bs_read_u16(bs); | |
| rec->endCharOffset = gf_bs_read_u16(bs); | |
| rec->fontID = gf_bs_read_u16(bs); | |
| rec->style_flags = gf_bs_read_u8(bs); | |
| rec->font_size = gf_bs_read_u8(bs); | |
| rec->text_color = gpp_read_rgba(bs); | |
| } | |
| GF_Err tx3g_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem) | |
| { | |
| GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s; | |
| switch (a->type) { | |
| case GF_ISOM_BOX_TYPE_FTAB: | |
| BOX_FIELD_ASSIGN(font_table, GF_FontTableBox) | |
| break; | |
| default: | |
| return GF_OK; | |
| } | |
| return GF_OK; | |
| } | |
| GF_Err tx3g_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s; | |
| ISOM_DECREASE_SIZE(ptr, (18 + GPP_BOX_SIZE + GPP_STYLE_SIZE) ); | |
| e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs); | |
| if (e) return e; | |
| ptr->displayFlags = gf_bs_read_u32(bs); | |
| ptr->horizontal_justification = gf_bs_read_u8(bs); | |
| ptr->vertical_justification = gf_bs_read_u8(bs); | |
| ptr->back_color = gpp_read_rgba(bs); | |
| gpp_read_box(bs, &ptr->default_box); | |
| gpp_read_style(bs, &ptr->default_style); | |
| return gf_isom_box_array_read(s, bs); | |
| } | |
| /*this is a quicktime specific box - see apple documentation*/ | |
| GF_Err text_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| u16 pSize; | |
| GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; | |
| ISOM_DECREASE_SIZE(ptr, 8); | |
| e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs); | |
| if (e) return e; | |
| ptr->textJustification = 1; | |
| //some weird text entries are not QT text nor 3gpp, cf issue #1030 | |
| if (!ptr->size) { | |
| return GF_OK; | |
| } | |
| if (ptr->size < 43) { | |
| GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Broken text box (%d bytes but min 43 required), skipping parsing.\n", ptr->size)); | |
| return GF_OK; | |
| } | |
| ISOM_DECREASE_SIZE(ptr, 43); | |
| ptr->displayFlags = gf_bs_read_u32(bs); /*Display flags*/ | |
| ptr->textJustification = gf_bs_read_u32(bs); /*Text justification*/ | |
| gf_bs_read_data(bs, ptr->background_color, 6); /*Background color*/ | |
| gpp_read_box(bs, &ptr->default_box); /*Default text box*/ | |
| gf_bs_read_data(bs, ptr->reserved1, 8); /*Reserved*/ | |
| ptr->fontNumber = gf_bs_read_u16(bs); /*Font number*/ | |
| ptr->fontFace = gf_bs_read_u16(bs); /*Font face*/ | |
| ptr->reserved2 = gf_bs_read_u8(bs); /*Reserved*/ | |
| ptr->reserved3 = gf_bs_read_u16(bs); /*Reserved*/ | |
| gf_bs_read_data(bs, ptr->foreground_color, 6); /*Foreground color*/ | |
| /*ffmpeg compatibility with iPod streams: no pascal string*/ | |
| if (!ptr->size) | |
| return GF_OK; | |
| ISOM_DECREASE_SIZE(ptr, 1); | |
| pSize = gf_bs_read_u8(bs); /*a Pascal string begins with its size: get textName size*/ | |
| if (ptr->size < pSize) { | |
| u32 b_size = pSize; | |
| size_t i = 0; | |
| GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] text box doesn't use a Pascal string: trying to decode anyway.\n")); | |
| ptr->textName = (char*)gf_malloc((size_t)ptr->size + 1 + 1); | |
| if (!ptr->textName) return GF_OUT_OF_MEM; | |
| do { | |
| char c = (char)b_size; | |
| if (c == '\0') { | |
| break; | |
| } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { | |
| ptr->textName[i] = c; | |
| } else { | |
| gf_free(ptr->textName); | |
| ptr->textName = NULL; | |
| GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] text box doesn't use a Pascal string and contains non-chars. Abort.\n")); | |
| return GF_ISOM_INVALID_FILE; | |
| } | |
| i++; | |
| if (!ptr->size) | |
| break; | |
| ptr->size--; | |
| b_size = gf_bs_read_u8(bs); | |
| } while (b_size); | |
| ptr->textName[i] = '\0'; /*Font name*/ | |
| GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] text box doesn't use a Pascal string: \"%s\" detected.\n", ptr->textName)); | |
| return GF_OK; | |
| } | |
| if (pSize) { | |
| ptr->textName = (char*) gf_malloc((pSize+1) * sizeof(char)); | |
| if (!ptr->textName) return GF_OUT_OF_MEM; | |
| if (gf_bs_read_data(bs, ptr->textName, pSize) != pSize) { | |
| gf_free(ptr->textName); | |
| ptr->textName = NULL; | |
| return GF_ISOM_INVALID_FILE; | |
| } | |
| ptr->textName[pSize] = '\0'; /*Font name*/ | |
| } | |
| ISOM_DECREASE_SIZE(ptr, pSize); | |
| if (!ptr->size) return GF_OK; | |
| u32 next_size = gf_bs_peek_bits(bs, 32, 0); | |
| if (next_size > ptr->size) { | |
| GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Broken text box detected, skipping parsing.\n")); | |
| ptr->textJustification = 1; | |
| return GF_OK; | |
| } | |
| return gf_isom_box_array_read(s, bs); | |
| } | |
| void gpp_write_rgba(GF_BitStream *bs, u32 col) | |
| { | |
| gf_bs_write_u8(bs, (col>>16) & 0xFF); | |
| gf_bs_write_u8(bs, (col>>8) & 0xFF); | |
| gf_bs_write_u8(bs, (col) & 0xFF); | |
| gf_bs_write_u8(bs, (col>>24) & 0xFF); | |
| } | |
| void gpp_write_box(GF_BitStream *bs, GF_BoxRecord *rec) | |
| { | |
| gf_bs_write_u16(bs, rec->top); | |
| gf_bs_write_u16(bs, rec->left); | |
| gf_bs_write_u16(bs, rec->bottom); | |
| gf_bs_write_u16(bs, rec->right); | |
| } | |
| #define GPP_STYLE_SIZE 12 | |
| void gpp_write_style(GF_BitStream *bs, GF_StyleRecord *rec) | |
| { | |
| gf_bs_write_u16(bs, rec->startCharOffset); | |
| gf_bs_write_u16(bs, rec->endCharOffset); | |
| gf_bs_write_u16(bs, rec->fontID); | |
| gf_bs_write_u8(bs, rec->style_flags); | |
| gf_bs_write_u8(bs, rec->font_size); | |
| gpp_write_rgba(bs, rec->text_color); | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err tx3g_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_data(bs, ptr->reserved, 6); | |
| gf_bs_write_u16(bs, ptr->dataReferenceIndex); | |
| gf_bs_write_u32(bs, ptr->displayFlags); | |
| gf_bs_write_u8(bs, ptr->horizontal_justification); | |
| gf_bs_write_u8(bs, ptr->vertical_justification); | |
| gpp_write_rgba(bs, ptr->back_color); | |
| gpp_write_box(bs, &ptr->default_box); | |
| gpp_write_style(bs, &ptr->default_style); | |
| return GF_OK; | |
| } | |
| GF_Err text_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| u16 pSize; | |
| GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_data(bs, ptr->reserved, 6); | |
| gf_bs_write_u16(bs, ptr->dataReferenceIndex); | |
| gf_bs_write_u32(bs, ptr->displayFlags); /*Display flags*/ | |
| gf_bs_write_u32(bs, ptr->textJustification); /*Text justification*/ | |
| gf_bs_write_data(bs, ptr->background_color, 6); /*Background color*/ | |
| gpp_write_box(bs, &ptr->default_box); /*Default text box*/ | |
| gf_bs_write_data(bs, ptr->reserved1, 8); /*Reserved*/ | |
| gf_bs_write_u16(bs, ptr->fontNumber); /*Font number*/ | |
| gf_bs_write_u16(bs, ptr->fontFace); /*Font face*/ | |
| gf_bs_write_u8(bs, ptr->reserved2); /*Reserved*/ | |
| gf_bs_write_u16(bs, ptr->reserved3); /*Reserved*/ | |
| gf_bs_write_data(bs, ptr->foreground_color, 6); /*Foreground color*/ | |
| //pSize assignment below is not a mistake | |
| if (ptr->textName && (pSize = (u16) strlen(ptr->textName))) { | |
| gf_bs_write_u8(bs, pSize); /*a Pascal string begins with its size*/ | |
| gf_bs_write_data(bs, ptr->textName, pSize); /*Font name*/ | |
| } else { | |
| gf_bs_write_u8(bs, 0); | |
| } | |
| return GF_OK; | |
| } | |
| GF_Err tx3g_box_size(GF_Box *s) | |
| { | |
| /*base + this + box + style*/ | |
| s->size += 18 + GPP_BOX_SIZE + GPP_STYLE_SIZE; | |
| return GF_OK; | |
| } | |
| GF_Err text_box_size(GF_Box *s) | |
| { | |
| GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; | |
| s->size += 8; | |
| /*base + this + string length*/ | |
| s->size += 43 + 1; | |
| if (ptr->textName) | |
| s->size += strlen(ptr->textName); | |
| return GF_OK; | |
| } | |
| #endif | |
| GF_Box *styl_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_TextStyleBox, GF_ISOM_BOX_TYPE_STYL); | |
| return (GF_Box *) tmp; | |
| } | |
| void styl_box_del(GF_Box *s) | |
| { | |
| GF_TextStyleBox*ptr = (GF_TextStyleBox*)s; | |
| if (ptr->styles) gf_free(ptr->styles); | |
| gf_free(ptr); | |
| } | |
| GF_Err styl_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| u32 i; | |
| GF_TextStyleBox*ptr = (GF_TextStyleBox*)s; | |
| ISOM_DECREASE_SIZE(ptr, 2); | |
| ptr->entry_count = gf_bs_read_u16(bs); | |
| if (ptr->size / GPP_STYLE_SIZE < ptr->entry_count) | |
| return GF_ISOM_INVALID_FILE; | |
| if (ptr->entry_count) { | |
| ptr->styles = (GF_StyleRecord*)gf_malloc(sizeof(GF_StyleRecord)*ptr->entry_count); | |
| if (!ptr->styles) return GF_OUT_OF_MEM; | |
| for (i=0; i<ptr->entry_count; i++) { | |
| ISOM_DECREASE_SIZE(ptr, GPP_STYLE_SIZE); | |
| gpp_read_style(bs, &ptr->styles[i]); | |
| } | |
| } | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err styl_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| u32 i; | |
| GF_TextStyleBox*ptr = (GF_TextStyleBox*)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_u16(bs, ptr->entry_count); | |
| for (i=0; i<ptr->entry_count; i++) gpp_write_style(bs, &ptr->styles[i]); | |
| return GF_OK; | |
| } | |
| GF_Err styl_box_size(GF_Box *s) | |
| { | |
| GF_TextStyleBox*ptr = (GF_TextStyleBox*)s; | |
| s->size += 2 + ptr->entry_count * GPP_STYLE_SIZE; | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *hlit_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_TextHighlightBox, GF_ISOM_BOX_TYPE_HLIT); | |
| return (GF_Box *) tmp; | |
| } | |
| void hlit_box_del(GF_Box *s) | |
| { | |
| gf_free(s); | |
| } | |
| GF_Err hlit_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_TextHighlightBox *ptr = (GF_TextHighlightBox *)s; | |
| ISOM_DECREASE_SIZE(ptr, 4) | |
| ptr->startcharoffset = gf_bs_read_u16(bs); | |
| ptr->endcharoffset = gf_bs_read_u16(bs); | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err hlit_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| GF_TextHighlightBox *ptr = (GF_TextHighlightBox *)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_u16(bs, ptr->startcharoffset); | |
| gf_bs_write_u16(bs, ptr->endcharoffset); | |
| return GF_OK; | |
| } | |
| GF_Err hlit_box_size(GF_Box *s) | |
| { | |
| s->size += 4; | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *hclr_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_TextHighlightColorBox, GF_ISOM_BOX_TYPE_HCLR); | |
| return (GF_Box *) tmp; | |
| } | |
| void hclr_box_del(GF_Box *s) | |
| { | |
| gf_free(s); | |
| } | |
| GF_Err hclr_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_TextHighlightColorBox*ptr = (GF_TextHighlightColorBox*)s; | |
| ISOM_DECREASE_SIZE(ptr, 4) | |
| ptr->hil_color = gpp_read_rgba(bs); | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err hclr_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| GF_TextHighlightColorBox*ptr = (GF_TextHighlightColorBox*)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gpp_write_rgba(bs, ptr->hil_color); | |
| return GF_OK; | |
| } | |
| GF_Err hclr_box_size(GF_Box *s) | |
| { | |
| s->size += 4; | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *krok_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_TextKaraokeBox, GF_ISOM_BOX_TYPE_KROK); | |
| return (GF_Box *) tmp; | |
| } | |
| void krok_box_del(GF_Box *s) | |
| { | |
| GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s; | |
| if (ptr->records) gf_free(ptr->records); | |
| gf_free(ptr); | |
| } | |
| GF_Err krok_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s; | |
| ISOM_DECREASE_SIZE(ptr, 6) | |
| ptr->highlight_starttime = gf_bs_read_u32(bs); | |
| ptr->nb_entries = gf_bs_read_u16(bs); | |
| if (ptr->size / 8 < ptr->nb_entries) | |
| return GF_ISOM_INVALID_FILE; | |
| if (ptr->nb_entries) { | |
| u32 i; | |
| ptr->records = (KaraokeRecord*)gf_malloc(sizeof(KaraokeRecord)*ptr->nb_entries); | |
| if (!ptr->records) return GF_OUT_OF_MEM; | |
| for (i=0; i<ptr->nb_entries; i++) { | |
| ISOM_DECREASE_SIZE(ptr, 8) | |
| ptr->records[i].highlight_endtime = gf_bs_read_u32(bs); | |
| ptr->records[i].start_charoffset = gf_bs_read_u16(bs); | |
| ptr->records[i].end_charoffset = gf_bs_read_u16(bs); | |
| } | |
| } | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err krok_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| u32 i; | |
| GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_u32(bs, ptr->highlight_starttime); | |
| gf_bs_write_u16(bs, ptr->nb_entries); | |
| for (i=0; i<ptr->nb_entries; i++) { | |
| gf_bs_write_u32(bs, ptr->records[i].highlight_endtime); | |
| gf_bs_write_u16(bs, ptr->records[i].start_charoffset); | |
| gf_bs_write_u16(bs, ptr->records[i].end_charoffset); | |
| } | |
| return GF_OK; | |
| } | |
| GF_Err krok_box_size(GF_Box *s) | |
| { | |
| GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s; | |
| s->size += 6 + 8*ptr->nb_entries; | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *dlay_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_TextScrollDelayBox, GF_ISOM_BOX_TYPE_DLAY); | |
| return (GF_Box *) tmp; | |
| } | |
| void dlay_box_del(GF_Box *s) | |
| { | |
| gf_free(s); | |
| } | |
| GF_Err dlay_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_TextScrollDelayBox*ptr = (GF_TextScrollDelayBox*)s; | |
| ISOM_DECREASE_SIZE(ptr, 4) | |
| ptr->scroll_delay = gf_bs_read_u32(bs); | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err dlay_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| GF_TextScrollDelayBox*ptr = (GF_TextScrollDelayBox*)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_u32(bs, ptr->scroll_delay); | |
| return GF_OK; | |
| } | |
| GF_Err dlay_box_size(GF_Box *s) | |
| { | |
| s->size += 4; | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *href_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_TextHyperTextBox, GF_ISOM_BOX_TYPE_HREF); | |
| return (GF_Box *) tmp; | |
| } | |
| void href_box_del(GF_Box *s) | |
| { | |
| GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s; | |
| if (ptr->URL) gf_free(ptr->URL); | |
| if (ptr->URL_hint) gf_free(ptr->URL_hint); | |
| gf_free(ptr); | |
| } | |
| GF_Err href_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| u32 len; | |
| GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s; | |
| ISOM_DECREASE_SIZE(ptr, 6) //including 2 length fields | |
| ptr->startcharoffset = gf_bs_read_u16(bs); | |
| ptr->endcharoffset = gf_bs_read_u16(bs); | |
| len = gf_bs_read_u8(bs); | |
| if (len) { | |
| ISOM_DECREASE_SIZE(ptr, len) | |
| ptr->URL = (char *) gf_malloc(sizeof(char) * (len+1)); | |
| if (!ptr->URL) return GF_OUT_OF_MEM; | |
| gf_bs_read_data(bs, ptr->URL, len); | |
| ptr->URL[len] = 0; | |
| } | |
| len = gf_bs_read_u8(bs); | |
| if (len) { | |
| ISOM_DECREASE_SIZE(ptr, len) | |
| ptr->URL_hint = (char *) gf_malloc(sizeof(char) * (len+1)); | |
| if (!ptr->URL_hint) return GF_OUT_OF_MEM; | |
| gf_bs_read_data(bs, ptr->URL_hint, len); | |
| ptr->URL_hint[len]= 0; | |
| } | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err href_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| u32 len; | |
| GF_Err e; | |
| GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_u16(bs, ptr->startcharoffset); | |
| gf_bs_write_u16(bs, ptr->endcharoffset); | |
| if (ptr->URL) { | |
| len = (u32) strlen(ptr->URL); | |
| gf_bs_write_u8(bs, len); | |
| gf_bs_write_data(bs, ptr->URL, len); | |
| } else { | |
| gf_bs_write_u8(bs, 0); | |
| } | |
| if (ptr->URL_hint) { | |
| len = (u32) strlen(ptr->URL_hint); | |
| gf_bs_write_u8(bs, len); | |
| gf_bs_write_data(bs, ptr->URL_hint, len); | |
| } else { | |
| gf_bs_write_u8(bs, 0); | |
| } | |
| return GF_OK; | |
| } | |
| GF_Err href_box_size(GF_Box *s) | |
| { | |
| GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s; | |
| s->size += 6; | |
| if (ptr->URL) s->size += strlen(ptr->URL); | |
| if (ptr->URL_hint) s->size += strlen(ptr->URL_hint); | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *tbox_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_TextBoxBox, GF_ISOM_BOX_TYPE_TBOX); | |
| return (GF_Box *) tmp; | |
| } | |
| void tbox_box_del(GF_Box *s) | |
| { | |
| gf_free(s); | |
| } | |
| GF_Err tbox_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_TextBoxBox*ptr = (GF_TextBoxBox*)s; | |
| ISOM_DECREASE_SIZE(ptr, GPP_BOX_SIZE) | |
| gpp_read_box(bs, &ptr->box); | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err tbox_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| GF_TextBoxBox*ptr = (GF_TextBoxBox*)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gpp_write_box(bs, &ptr->box); | |
| return GF_OK; | |
| } | |
| GF_Err tbox_box_size(GF_Box *s) | |
| { | |
| s->size += 8; | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *blnk_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_TextBlinkBox, GF_ISOM_BOX_TYPE_BLNK); | |
| return (GF_Box *) tmp; | |
| } | |
| void blnk_box_del(GF_Box *s) | |
| { | |
| gf_free(s); | |
| } | |
| GF_Err blnk_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_TextBlinkBox*ptr = (GF_TextBlinkBox*)s; | |
| ISOM_DECREASE_SIZE(ptr, 4) | |
| ptr->startcharoffset = gf_bs_read_u16(bs); | |
| ptr->endcharoffset = gf_bs_read_u16(bs); | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err blnk_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| GF_TextBlinkBox*ptr = (GF_TextBlinkBox*)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_u16(bs, ptr->startcharoffset); | |
| gf_bs_write_u16(bs, ptr->endcharoffset); | |
| return GF_OK; | |
| } | |
| GF_Err blnk_box_size(GF_Box *s) | |
| { | |
| s->size += 4; | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *twrp_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_TextWrapBox, GF_ISOM_BOX_TYPE_TWRP); | |
| return (GF_Box *) tmp; | |
| } | |
| void twrp_box_del(GF_Box *s) | |
| { | |
| gf_free(s); | |
| } | |
| GF_Err twrp_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_TextWrapBox*ptr = (GF_TextWrapBox*)s; | |
| ISOM_DECREASE_SIZE(ptr, 1) | |
| ptr->wrap_flag = gf_bs_read_u8(bs); | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err twrp_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| GF_TextWrapBox*ptr = (GF_TextWrapBox*)s; | |
| e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_u8(bs, ptr->wrap_flag); | |
| return GF_OK; | |
| } | |
| GF_Err twrp_box_size(GF_Box *s) | |
| { | |
| s->size += 1; | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| void tsel_box_del(GF_Box *s) | |
| { | |
| GF_TrackSelectionBox *ptr; | |
| ptr = (GF_TrackSelectionBox *) s; | |
| if (ptr == NULL) return; | |
| if (ptr->attributeList) gf_free(ptr->attributeList); | |
| gf_free(ptr); | |
| } | |
| GF_Err tsel_box_read(GF_Box *s,GF_BitStream *bs) | |
| { | |
| u32 i; | |
| GF_TrackSelectionBox *ptr = (GF_TrackSelectionBox *) s; | |
| ISOM_DECREASE_SIZE(ptr, 4); | |
| ptr->switchGroup = gf_bs_read_u32(bs); | |
| if (ptr->size % 4) return GF_ISOM_INVALID_FILE; | |
| ptr->attributeListCount = (u32)ptr->size/4; | |
| ptr->attributeList = gf_malloc(ptr->attributeListCount*sizeof(u32)); | |
| if (ptr->attributeList == NULL) return GF_OUT_OF_MEM; | |
| for (i=0; i< ptr->attributeListCount; i++) { | |
| ptr->attributeList[i] = gf_bs_read_u32(bs); | |
| } | |
| return GF_OK; | |
| } | |
| GF_Box *tsel_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_TrackSelectionBox, GF_ISOM_BOX_TYPE_TSEL); | |
| return (GF_Box *)tmp; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err tsel_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| u32 i; | |
| GF_TrackSelectionBox *ptr = (GF_TrackSelectionBox *) s; | |
| e = gf_isom_full_box_write(s, bs); | |
| if (e) return e; | |
| gf_bs_write_u32(bs,ptr->switchGroup); | |
| for (i = 0; i < ptr->attributeListCount; i++ ) { | |
| gf_bs_write_u32(bs, ptr->attributeList[i]); | |
| } | |
| return GF_OK; | |
| } | |
| GF_Err tsel_box_size(GF_Box *s) | |
| { | |
| GF_TrackSelectionBox *ptr = (GF_TrackSelectionBox *) s; | |
| ptr->size += 4 + (4*ptr->attributeListCount); | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *dimC_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_DIMSSceneConfigBox, GF_ISOM_BOX_TYPE_DIMC); | |
| return (GF_Box *)tmp; | |
| } | |
| void dimC_box_del(GF_Box *s) | |
| { | |
| GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s; | |
| if (p->contentEncoding) gf_free(p->contentEncoding); | |
| if (p->textEncoding) gf_free(p->textEncoding); | |
| gf_free(p); | |
| } | |
| GF_Err dimC_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| u32 i, msize; | |
| GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s; | |
| ISOM_DECREASE_SIZE(p, 3); | |
| p->profile = gf_bs_read_u8(bs); | |
| p->level = gf_bs_read_u8(bs); | |
| p->pathComponents = gf_bs_read_int(bs, 4); | |
| p->fullRequestHost = gf_bs_read_int(bs, 1); | |
| p->streamType = gf_bs_read_int(bs, 1); | |
| p->containsRedundant = gf_bs_read_int(bs, 2); | |
| if (p->size > GF_UINT_MAX-1) return GF_ISOM_INVALID_FILE; | |
| char *str = gf_malloc( (size_t) (p->size+1)); | |
| if (!str) return GF_OUT_OF_MEM; | |
| msize = (u32) p->size; | |
| str[msize] = 0; | |
| i=0; | |
| str[0]=0; | |
| while (i < msize) { | |
| ISOM_DECREASE_SIZE_GOTO_EXIT(p, 1); | |
| str[i] = gf_bs_read_u8(bs); | |
| if (!str[i]) break; | |
| i++; | |
| } | |
| if (i == msize) { | |
| gf_free(str); | |
| return GF_ISOM_INVALID_FILE; | |
| } | |
| p->textEncoding = gf_strdup(str); | |
| i=0; | |
| str[0]=0; | |
| while (i < msize) { | |
| ISOM_DECREASE_SIZE_GOTO_EXIT(p, 1); | |
| str[i] = gf_bs_read_u8(bs); | |
| if (!str[i]) break; | |
| i++; | |
| } | |
| if (i == msize) { | |
| gf_free(str); | |
| return GF_ISOM_INVALID_FILE; | |
| } | |
| p->contentEncoding = gf_strdup(str); | |
| gf_free(str); | |
| if (!p->textEncoding || !p->contentEncoding) | |
| return GF_OUT_OF_MEM; | |
| return GF_OK; | |
| exit: | |
| gf_free(str); | |
| return e; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err dimC_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s; | |
| GF_Err e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_u8(bs, p->profile); | |
| gf_bs_write_u8(bs, p->level); | |
| gf_bs_write_int(bs, p->pathComponents, 4); | |
| gf_bs_write_int(bs, p->fullRequestHost, 1); | |
| gf_bs_write_int(bs, p->streamType, 1); | |
| gf_bs_write_int(bs, p->containsRedundant, 2); | |
| if (p->textEncoding) | |
| gf_bs_write_data(bs, p->textEncoding, (u32) strlen(p->textEncoding)); | |
| gf_bs_write_u8(bs, 0); | |
| if (p->contentEncoding) | |
| gf_bs_write_data(bs, p->contentEncoding, (u32) strlen(p->contentEncoding)); | |
| gf_bs_write_u8(bs, 0); | |
| return GF_OK; | |
| } | |
| GF_Err dimC_box_size(GF_Box *s) | |
| { | |
| GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s; | |
| s->size += 3 + 2; | |
| if (p->textEncoding) s->size += strlen(p->textEncoding); | |
| if (p->contentEncoding) s->size += strlen(p->contentEncoding); | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *diST_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_DIMSScriptTypesBox, GF_ISOM_BOX_TYPE_DIST); | |
| return (GF_Box *)tmp; | |
| } | |
| void diST_box_del(GF_Box *s) | |
| { | |
| GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s; | |
| if (p->content_script_types) gf_free(p->content_script_types); | |
| gf_free(p); | |
| } | |
| GF_Err diST_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s; | |
| if (s->size > GF_UINT_MAX-1) return GF_ISOM_INVALID_FILE; | |
| p->content_script_types = gf_malloc(sizeof(u8) * ((u32) s->size + 1)); | |
| if (!p->content_script_types) return GF_OUT_OF_MEM; | |
| gf_bs_read_data(bs, p->content_script_types, (u32) s->size); | |
| p->content_script_types[(u32) s->size] = 0; | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err diST_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s; | |
| GF_Err e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| if (p->content_script_types) | |
| gf_bs_write_data(bs, p->content_script_types, (u32) strlen(p->content_script_types)+1); | |
| else | |
| gf_bs_write_u8(bs, 0); | |
| return GF_OK; | |
| } | |
| GF_Err diST_box_size(GF_Box *s) | |
| { | |
| GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s; | |
| s->size += p->content_script_types ? (strlen(p->content_script_types)+1) : 1; | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| GF_Box *dims_box_new() | |
| { | |
| ISOM_DECL_BOX_ALLOC(GF_DIMSSampleEntryBox, GF_ISOM_BOX_TYPE_DIMS); | |
| gf_isom_sample_entry_init((GF_SampleEntryBox *)tmp); | |
| return (GF_Box*)tmp; | |
| } | |
| void dims_box_del(GF_Box *s) | |
| { | |
| gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s); | |
| gf_free(s); | |
| } | |
| GF_Err dims_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem) | |
| { | |
| GF_DIMSSampleEntryBox *ptr = (GF_DIMSSampleEntryBox *)s; | |
| switch (a->type) { | |
| case GF_ISOM_BOX_TYPE_DIMC: | |
| BOX_FIELD_ASSIGN(config, GF_DIMSSceneConfigBox) | |
| break; | |
| case GF_ISOM_BOX_TYPE_DIST: | |
| BOX_FIELD_ASSIGN(scripts, GF_DIMSScriptTypesBox) | |
| break; | |
| } | |
| return GF_OK; | |
| } | |
| GF_Err dims_box_read(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_Err e; | |
| GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s; | |
| e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)p, bs); | |
| if (e) return e; | |
| ISOM_DECREASE_SIZE(p, 8); | |
| return gf_isom_box_array_read(s, bs); | |
| } | |
| #ifndef GPAC_DISABLE_ISOM_WRITE | |
| GF_Err dims_box_write(GF_Box *s, GF_BitStream *bs) | |
| { | |
| GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s; | |
| GF_Err e = gf_isom_box_write_header(s, bs); | |
| if (e) return e; | |
| gf_bs_write_data(bs, p->reserved, 6); | |
| gf_bs_write_u16(bs, p->dataReferenceIndex); | |
| return GF_OK; | |
| } | |
| GF_Err dims_box_size(GF_Box *s) | |
| { | |
| u32 pos = 0; | |
| GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s; | |
| s->size += 8; | |
| gf_isom_check_position(s, (GF_Box *) p->config, &pos); | |
| gf_isom_check_position(s, (GF_Box *) p->scripts, &pos); | |
| return GF_OK; | |
| } | |
| #endif /*GPAC_DISABLE_ISOM_WRITE*/ | |
| #endif /*GPAC_DISABLE_ISOM*/ |