Coverage Report

Created: 2026-05-30 07:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpac/src/isomedia/box_code_3gpp.c
Line
Count
Source
1
/*
2
 *      GPAC - Multimedia Framework C SDK
3
 *
4
 *      Authors: Jean Le Feuvre
5
 *      Copyright (c) Telecom ParisTech 2000-2023
6
 *          All rights reserved
7
 *
8
 *  This file is part of GPAC / ISO Media File Format sub-project
9
 *
10
 *  GPAC is free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU Lesser General Public License as published by
12
 *  the Free Software Foundation; either version 2, or (at your option)
13
 *  any later version.
14
 *
15
 *  GPAC is distributed in the hope that it will be useful,
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 *  GNU Lesser General Public License for more details.
19
 *
20
 *  You should have received a copy of the GNU Lesser General Public
21
 *  License along with this library; see the file COPYING.  If not, write to
22
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
 *
24
 */
25
26
#include <gpac/internal/isomedia_dev.h>
27
#include <gpac/tools.h>
28
29
#ifndef GPAC_DISABLE_ISOM
30
31
32
33
GF_Box *gppc_box_new()
34
1.83k
{
35
  //default type is amr but overwritten by box constructor
36
1.83k
  ISOM_DECL_BOX_ALLOC(GF_3GPPConfigBox, GF_ISOM_BOX_TYPE_DAMR);
37
1.83k
  return (GF_Box *)tmp;
38
1.83k
}
39
40
void gppc_box_del(GF_Box *s)
41
1.83k
{
42
1.83k
  GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s;
43
1.83k
  if (ptr == NULL) return;
44
1.83k
  gf_free(ptr);
45
1.83k
}
46
47
48
GF_Err gppc_box_read(GF_Box *s, GF_BitStream *bs)
49
1.82k
{
50
1.82k
  GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s;
51
1.82k
  if (ptr == NULL) return GF_BAD_PARAM;
52
1.82k
  memset(&ptr->cfg, 0, sizeof(GF_3GPConfig));
53
54
1.82k
  ISOM_DECREASE_SIZE(s, 5)
55
1.71k
  ptr->cfg.vendor = gf_bs_read_u32(bs);
56
1.71k
  ptr->cfg.decoder_version = gf_bs_read_u8(bs);
57
58
1.71k
  switch (ptr->type) {
59
655
  case GF_ISOM_BOX_TYPE_D263:
60
655
    ISOM_DECREASE_SIZE(s, 2)
61
568
    ptr->cfg.H263_level = gf_bs_read_u8(bs);
62
568
    ptr->cfg.H263_profile = gf_bs_read_u8(bs);
63
568
    break;
64
575
  case GF_ISOM_BOX_TYPE_DAMR:
65
575
    ISOM_DECREASE_SIZE(s, 4)
66
319
    ptr->cfg.AMR_mode_set = gf_bs_read_u16(bs);
67
319
    ptr->cfg.AMR_mode_change_period = gf_bs_read_u8(bs);
68
319
    ptr->cfg.frames_per_sample = gf_bs_read_u8(bs);
69
319
    break;
70
305
  case GF_ISOM_BOX_TYPE_DEVC:
71
385
  case GF_ISOM_BOX_TYPE_DQCP:
72
483
  case GF_ISOM_BOX_TYPE_DSMV:
73
483
    ISOM_DECREASE_SIZE(s, 1)
74
272
    ptr->cfg.frames_per_sample = gf_bs_read_u8(bs);
75
272
    break;
76
1.71k
  }
77
1.15k
  return GF_OK;
78
1.71k
}
79
80
#ifndef GPAC_DISABLE_ISOM_WRITE
81
82
GF_Err gppc_box_write(GF_Box *s, GF_BitStream *bs)
83
0
{
84
0
  GF_Err e;
85
0
  GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s;
86
0
  e = gf_isom_box_write_header(s, bs);
87
0
  if (e) return e;
88
89
0
  gf_bs_write_u32(bs, ptr->cfg.vendor);
90
0
  gf_bs_write_u8(bs, ptr->cfg.decoder_version);
91
0
  switch (ptr->cfg.type) {
92
0
  case GF_ISOM_SUBTYPE_3GP_H263:
93
0
    gf_bs_write_u8(bs, ptr->cfg.H263_level);
94
0
    gf_bs_write_u8(bs, ptr->cfg.H263_profile);
95
0
    break;
96
0
  case GF_ISOM_SUBTYPE_3GP_AMR:
97
0
  case GF_ISOM_SUBTYPE_3GP_AMR_WB:
98
0
    gf_bs_write_u16(bs, ptr->cfg.AMR_mode_set);
99
0
    gf_bs_write_u8(bs, ptr->cfg.AMR_mode_change_period);
100
0
    gf_bs_write_u8(bs, ptr->cfg.frames_per_sample);
101
0
    break;
102
0
  case GF_ISOM_SUBTYPE_3GP_EVRC:
103
0
  case GF_ISOM_SUBTYPE_3GP_QCELP:
104
0
  case GF_ISOM_SUBTYPE_3GP_SMV:
105
0
    gf_bs_write_u8(bs, ptr->cfg.frames_per_sample);
106
0
    break;
107
0
  }
108
0
  return GF_OK;
109
0
}
110
111
GF_Err gppc_box_size(GF_Box *s)
112
0
{
113
0
  GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s;
114
115
0
  s->size += 5;
116
0
  if (!ptr->cfg.type) {
117
0
    switch (ptr->type) {
118
0
    case GF_ISOM_BOX_TYPE_D263:
119
0
      ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_H263;
120
0
      break;
121
0
    case GF_ISOM_BOX_TYPE_DAMR:
122
0
      ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_AMR;
123
0
      break;
124
0
    case GF_ISOM_BOX_TYPE_DEVC:
125
0
      ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_EVRC;
126
0
      break;
127
0
    case GF_ISOM_BOX_TYPE_DQCP:
128
0
      ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_QCELP;
129
0
      break;
130
0
    case GF_ISOM_BOX_TYPE_DSMV:
131
0
      ptr->cfg.type = GF_ISOM_SUBTYPE_3GP_SMV;
132
0
      break;
133
0
    }
134
0
  }
135
0
  switch (ptr->cfg.type) {
136
0
  case GF_ISOM_SUBTYPE_3GP_H263:
137
0
    s->size += 2;
138
0
    break;
139
0
  case GF_ISOM_SUBTYPE_3GP_AMR:
140
0
  case GF_ISOM_SUBTYPE_3GP_AMR_WB:
141
0
    s->size += 4;
142
0
    break;
143
0
  case GF_ISOM_SUBTYPE_3GP_EVRC:
144
0
  case GF_ISOM_SUBTYPE_3GP_QCELP:
145
0
  case GF_ISOM_SUBTYPE_3GP_SMV:
146
0
    s->size += 1;
147
0
    break;
148
0
  }
149
0
  return GF_OK;
150
0
}
151
152
#endif /*GPAC_DISABLE_ISOM_WRITE*/
153
154
155
GF_Box *ftab_box_new()
156
1.59k
{
157
1.59k
  ISOM_DECL_BOX_ALLOC(GF_FontTableBox, GF_ISOM_BOX_TYPE_FTAB);
158
1.59k
  return (GF_Box *) tmp;
159
1.59k
}
160
void ftab_box_del(GF_Box *s)
161
1.59k
{
162
1.59k
  GF_FontTableBox *ptr = (GF_FontTableBox *)s;
163
1.59k
  if (ptr->fonts) {
164
791
    u32 i;
165
22.1k
    for (i=0; i<ptr->entry_count; i++)
166
21.3k
      if (ptr->fonts[i].fontName) gf_free(ptr->fonts[i].fontName);
167
791
    gf_free(ptr->fonts);
168
791
  }
169
1.59k
  gf_free(ptr);
170
1.59k
}
171
GF_Err ftab_box_read(GF_Box *s, GF_BitStream *bs)
172
1.59k
{
173
1.59k
  u32 i;
174
1.59k
  GF_FontTableBox *ptr = (GF_FontTableBox *)s;
175
1.59k
  ptr->entry_count = gf_bs_read_u16(bs);
176
1.59k
  ISOM_DECREASE_SIZE(ptr, 2);
177
178
1.15k
  if (ptr->size<ptr->entry_count*3) {
179
366
    GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Corrupted ftap box, skipping\n"));
180
366
    ptr->entry_count = 0;
181
366
    return GF_OK;
182
366
  }
183
791
  ptr->fonts = (GF_FontRecord *) gf_malloc(sizeof(GF_FontRecord)*ptr->entry_count);
184
791
  if (!ptr->fonts) return GF_OUT_OF_MEM;
185
186
791
  memset(ptr->fonts, 0, sizeof(GF_FontRecord)*ptr->entry_count);
187
4.46k
  for (i=0; i<ptr->entry_count; i++) {
188
4.16k
    u32 len;
189
4.16k
    ISOM_DECREASE_SIZE(ptr, 3);
190
3.91k
    ptr->fonts[i].fontID = gf_bs_read_u16(bs);
191
3.91k
    len = gf_bs_read_u8(bs);
192
3.91k
    if (len) {
193
1.80k
      ISOM_DECREASE_SIZE(ptr, len);
194
1.56k
      ptr->fonts[i].fontName = (char *)gf_malloc(sizeof(char)*(len+1));
195
1.56k
      if (!ptr->fonts[i].fontName) return GF_OUT_OF_MEM;
196
1.56k
      gf_bs_read_data(bs, ptr->fonts[i].fontName, len);
197
1.56k
      ptr->fonts[i].fontName[len] = 0;
198
1.56k
    }
199
3.91k
  }
200
307
  return GF_OK;
201
791
}
202
203
#ifndef GPAC_DISABLE_ISOM_WRITE
204
GF_Err ftab_box_write(GF_Box *s, GF_BitStream *bs)
205
0
{
206
0
  GF_Err e;
207
0
  u32 i;
208
0
  GF_FontTableBox *ptr = (GF_FontTableBox *)s;
209
0
  e = gf_isom_box_write_header(s, bs);
210
0
  if (e) return e;
211
0
  gf_bs_write_u16(bs, ptr->entry_count);
212
0
  for (i=0; i<ptr->entry_count; i++) {
213
0
    gf_bs_write_u16(bs, ptr->fonts[i].fontID);
214
0
    if (ptr->fonts[i].fontName) {
215
0
      u32 len = (u32) strlen(ptr->fonts[i].fontName);
216
0
      gf_bs_write_u8(bs, len);
217
0
      gf_bs_write_data(bs, ptr->fonts[i].fontName, len);
218
0
    } else {
219
0
      gf_bs_write_u8(bs, 0);
220
0
    }
221
0
  }
222
0
  return GF_OK;
223
0
}
224
GF_Err ftab_box_size(GF_Box *s)
225
0
{
226
0
  u32 i;
227
0
  GF_FontTableBox *ptr = (GF_FontTableBox *)s;
228
229
0
  s->size += 2;
230
0
  for (i=0; i<ptr->entry_count; i++) {
231
0
    s->size += 3;
232
0
    if (ptr->fonts[i].fontName) s->size += strlen(ptr->fonts[i].fontName);
233
0
  }
234
0
  return GF_OK;
235
0
}
236
237
#endif /*GPAC_DISABLE_ISOM_WRITE*/
238
239
240
241
GF_Box *text_box_new()
242
2.71k
{
243
2.71k
  ISOM_DECL_BOX_ALLOC(GF_TextSampleEntryBox, GF_ISOM_BOX_TYPE_TEXT);
244
2.71k
  gf_isom_sample_entry_init((GF_SampleEntryBox *)tmp);
245
2.71k
  return (GF_Box *) tmp;
246
2.71k
}
247
248
void text_box_del(GF_Box *s)
249
2.71k
{
250
2.71k
  GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s;
251
2.71k
  gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
252
253
2.71k
  if (ptr->textName)
254
873
    gf_free(ptr->textName);
255
2.71k
  gf_free(ptr);
256
2.71k
}
257
258
GF_Box *tx3g_box_new()
259
302
{
260
302
  ISOM_DECL_BOX_ALLOC(GF_Tx3gSampleEntryBox, GF_ISOM_BOX_TYPE_TX3G);
261
302
  gf_isom_sample_entry_init((GF_SampleEntryBox *)tmp);
262
302
  return (GF_Box *) tmp;
263
302
}
264
265
void tx3g_box_del(GF_Box *s)
266
302
{
267
302
  gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
268
302
  gf_free(s);
269
302
}
270
271
u32 gpp_read_rgba(GF_BitStream *bs)
272
2.49k
{
273
2.49k
  u8 r, g, b, a;
274
2.49k
  u32 col;
275
2.49k
  r = gf_bs_read_u8(bs);
276
2.49k
  g = gf_bs_read_u8(bs);
277
2.49k
  b = gf_bs_read_u8(bs);
278
2.49k
  a = gf_bs_read_u8(bs);
279
2.49k
  col = a;
280
2.49k
  col<<=8;
281
2.49k
  col |= r;
282
2.49k
  col<<=8;
283
2.49k
  col |= g;
284
2.49k
  col<<=8;
285
2.49k
  col |= b;
286
2.49k
  return col;
287
2.49k
}
288
289
0
#define GPP_BOX_SIZE  8
290
void gpp_read_box(GF_BitStream *bs, GF_BoxRecord *rec)
291
2.50k
{
292
2.50k
  rec->top = gf_bs_read_u16(bs);
293
2.50k
  rec->left = gf_bs_read_u16(bs);
294
2.50k
  rec->bottom = gf_bs_read_u16(bs);
295
2.50k
  rec->right = gf_bs_read_u16(bs);
296
2.50k
}
297
298
#define GPP_STYLE_SIZE  12
299
void gpp_read_style(GF_BitStream *bs, GF_StyleRecord *rec)
300
2.04k
{
301
2.04k
  rec->startCharOffset = gf_bs_read_u16(bs);
302
2.04k
  rec->endCharOffset = gf_bs_read_u16(bs);
303
2.04k
  rec->fontID = gf_bs_read_u16(bs);
304
2.04k
  rec->style_flags = gf_bs_read_u8(bs);
305
2.04k
  rec->font_size = gf_bs_read_u8(bs);
306
2.04k
  rec->text_color = gpp_read_rgba(bs);
307
2.04k
}
308
309
GF_Err tx3g_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
310
447
{
311
447
  GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s;
312
447
  switch (a->type) {
313
310
  case GF_ISOM_BOX_TYPE_FTAB:
314
310
    BOX_FIELD_ASSIGN(font_table, GF_FontTableBox)
315
108
    break;
316
137
  default:
317
137
    return GF_OK;
318
447
  }
319
108
  return GF_OK;
320
447
}
321
322
GF_Err tx3g_box_read(GF_Box *s, GF_BitStream *bs)
323
302
{
324
302
  GF_Err e;
325
302
  GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s;
326
327
302
  ISOM_DECREASE_SIZE(ptr, (18 + GPP_BOX_SIZE + GPP_STYLE_SIZE) );
328
329
251
  e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
330
251
  if (e) return e;
331
332
251
  ptr->displayFlags = gf_bs_read_u32(bs);
333
251
  ptr->horizontal_justification = gf_bs_read_u8(bs);
334
251
  ptr->vertical_justification = gf_bs_read_u8(bs);
335
251
  ptr->back_color = gpp_read_rgba(bs);
336
251
  gpp_read_box(bs, &ptr->default_box);
337
251
  gpp_read_style(bs, &ptr->default_style);
338
339
340
251
  return gf_isom_box_array_read(s, bs);
341
251
}
342
343
/*this is a quicktime specific box - see apple documentation*/
344
GF_Err text_box_read(GF_Box *s, GF_BitStream *bs)
345
2.71k
{
346
2.71k
  GF_Err e;
347
2.71k
  u16 pSize;
348
2.71k
  GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s;
349
350
2.71k
  ISOM_DECREASE_SIZE(ptr, 8);
351
2.49k
  e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)ptr, bs);
352
2.49k
  if (e) return e;
353
354
2.49k
  ptr->textJustification = 1;
355
356
  //some weird text entries are not QT text nor 3gpp, cf issue #1030
357
2.49k
  if (!ptr->size) {
358
233
    return GF_OK;
359
233
  }
360
2.26k
  if (ptr->size < 43) {
361
233
    GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Broken text box (%d bytes but min 43 required), skipping parsing.\n", ptr->size));
362
233
    return GF_OK;
363
233
  }
364
4.05k
  ISOM_DECREASE_SIZE(ptr, 43);
365
366
4.05k
  ptr->displayFlags = gf_bs_read_u32(bs);     /*Display flags*/
367
4.05k
  ptr->textJustification = gf_bs_read_u32(bs);  /*Text justification*/
368
4.05k
  gf_bs_read_data(bs, ptr->background_color, 6);  /*Background color*/
369
4.05k
  gpp_read_box(bs, &ptr->default_box);      /*Default text box*/
370
4.05k
  gf_bs_read_data(bs, ptr->reserved1, 8);     /*Reserved*/
371
4.05k
  ptr->fontNumber = gf_bs_read_u16(bs);     /*Font number*/
372
4.05k
  ptr->fontFace   = gf_bs_read_u16(bs);     /*Font face*/
373
4.05k
  ptr->reserved2  = gf_bs_read_u8(bs);      /*Reserved*/
374
4.05k
  ptr->reserved3  = gf_bs_read_u16(bs);     /*Reserved*/
375
4.05k
  gf_bs_read_data(bs, ptr->foreground_color, 6);  /*Foreground color*/
376
377
  /*ffmpeg compatibility with iPod streams: no pascal string*/
378
4.05k
  if (!ptr->size)
379
324
    return GF_OK;
380
381
3.40k
  ISOM_DECREASE_SIZE(ptr, 1);
382
3.40k
  pSize = gf_bs_read_u8(bs); /*a Pascal string begins with its size: get textName size*/
383
384
3.40k
  if (ptr->size < pSize) {
385
1.05k
    u32 b_size = pSize;
386
1.05k
    size_t i = 0;
387
1.05k
    GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] text box doesn't use a Pascal string: trying to decode anyway.\n"));
388
1.05k
    ptr->textName = (char*)gf_malloc((size_t)ptr->size + 1 + 1);
389
1.05k
    if (!ptr->textName) return GF_OUT_OF_MEM;
390
391
2.68k
    do {
392
2.68k
      char c = (char)b_size;
393
2.68k
      if (c == '\0') {
394
0
        break;
395
2.68k
      } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
396
2.26k
        ptr->textName[i] = c;
397
2.26k
      } else {
398
417
        gf_free(ptr->textName);
399
417
        ptr->textName = NULL;
400
417
        GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] text box doesn't use a Pascal string and contains non-chars. Abort.\n"));
401
417
        return GF_ISOM_INVALID_FILE;
402
417
      }
403
2.26k
      i++;
404
2.26k
      if (!ptr->size)
405
314
        break;
406
1.94k
      ptr->size--;
407
1.94k
      b_size = gf_bs_read_u8(bs);
408
1.94k
    } while (b_size);
409
410
636
    ptr->textName[i] = '\0';        /*Font name*/
411
636
    GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] text box doesn't use a Pascal string: \"%s\" detected.\n", ptr->textName));
412
636
    return GF_OK;
413
1.05k
  }
414
650
  if (pSize) {
415
237
    ptr->textName = (char*) gf_malloc((pSize+1) * sizeof(char));
416
237
    if (!ptr->textName) return GF_OUT_OF_MEM;
417
418
237
    if (gf_bs_read_data(bs, ptr->textName, pSize) != pSize) {
419
0
      gf_free(ptr->textName);
420
0
      ptr->textName = NULL;
421
0
      return GF_ISOM_INVALID_FILE;
422
0
    }
423
237
    ptr->textName[pSize] = '\0';        /*Font name*/
424
237
  }
425
1.30k
  ISOM_DECREASE_SIZE(ptr, pSize);
426
427
1.30k
  if (!ptr->size) return GF_OK;
428
429
574
  u32 next_size = gf_bs_peek_bits(bs, 32, 0);
430
574
  if (next_size > ptr->size) {
431
315
    GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Broken text box detected, skipping parsing.\n"));
432
315
    ptr->textJustification = 1;
433
315
    return GF_OK;
434
315
  }
435
259
  return gf_isom_box_array_read(s, bs);
436
574
}
437
438
void gpp_write_rgba(GF_BitStream *bs, u32 col)
439
10.8k
{
440
10.8k
  gf_bs_write_u8(bs, (col>>16) & 0xFF);
441
10.8k
  gf_bs_write_u8(bs, (col>>8) & 0xFF);
442
10.8k
  gf_bs_write_u8(bs, (col) & 0xFF);
443
10.8k
  gf_bs_write_u8(bs, (col>>24) & 0xFF);
444
10.8k
}
445
446
void gpp_write_box(GF_BitStream *bs, GF_BoxRecord *rec)
447
38
{
448
38
  gf_bs_write_u16(bs, rec->top);
449
38
  gf_bs_write_u16(bs, rec->left);
450
38
  gf_bs_write_u16(bs, rec->bottom);
451
38
  gf_bs_write_u16(bs, rec->right);
452
38
}
453
454
2.22k
#define GPP_STYLE_SIZE  12
455
void gpp_write_style(GF_BitStream *bs, GF_StyleRecord *rec)
456
10.8k
{
457
10.8k
  gf_bs_write_u16(bs, rec->startCharOffset);
458
10.8k
  gf_bs_write_u16(bs, rec->endCharOffset);
459
10.8k
  gf_bs_write_u16(bs, rec->fontID);
460
10.8k
  gf_bs_write_u8(bs, rec->style_flags);
461
10.8k
  gf_bs_write_u8(bs, rec->font_size);
462
10.8k
  gpp_write_rgba(bs, rec->text_color);
463
10.8k
}
464
465
#ifndef GPAC_DISABLE_ISOM_WRITE
466
467
GF_Err tx3g_box_write(GF_Box *s, GF_BitStream *bs)
468
0
{
469
0
  GF_Err e;
470
0
  GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s;
471
472
0
  e = gf_isom_box_write_header(s, bs);
473
0
  if (e) return e;
474
0
  gf_bs_write_data(bs, ptr->reserved, 6);
475
0
  gf_bs_write_u16(bs, ptr->dataReferenceIndex);
476
0
  gf_bs_write_u32(bs, ptr->displayFlags);
477
0
  gf_bs_write_u8(bs, ptr->horizontal_justification);
478
0
  gf_bs_write_u8(bs, ptr->vertical_justification);
479
0
  gpp_write_rgba(bs, ptr->back_color);
480
0
  gpp_write_box(bs, &ptr->default_box);
481
0
  gpp_write_style(bs, &ptr->default_style);
482
0
  return GF_OK;
483
0
}
484
485
GF_Err text_box_write(GF_Box *s, GF_BitStream *bs)
486
0
{
487
0
  GF_Err e;
488
0
  u16 pSize;
489
0
  GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s;
490
491
0
  e = gf_isom_box_write_header(s, bs);
492
0
  if (e) return e;
493
0
  gf_bs_write_data(bs, ptr->reserved, 6);
494
0
  gf_bs_write_u16(bs, ptr->dataReferenceIndex);
495
496
0
  gf_bs_write_u32(bs, ptr->displayFlags);     /*Display flags*/
497
0
  gf_bs_write_u32(bs, ptr->textJustification);  /*Text justification*/
498
0
  gf_bs_write_data(bs, ptr->background_color, 6); /*Background color*/
499
0
  gpp_write_box(bs, &ptr->default_box);     /*Default text box*/
500
0
  gf_bs_write_data(bs, ptr->reserved1, 8);    /*Reserved*/
501
0
  gf_bs_write_u16(bs, ptr->fontNumber);     /*Font number*/
502
0
  gf_bs_write_u16(bs, ptr->fontFace);       /*Font face*/
503
0
  gf_bs_write_u8(bs, ptr->reserved2);       /*Reserved*/
504
0
  gf_bs_write_u16(bs, ptr->reserved3);      /*Reserved*/
505
0
  gf_bs_write_data(bs, ptr->foreground_color, 6); /*Foreground color*/
506
  //pSize assignment below is not a mistake
507
0
  if (ptr->textName && (pSize = (u16) strlen(ptr->textName))) {
508
0
    gf_bs_write_u8(bs, pSize);          /*a Pascal string begins with its size*/
509
0
    gf_bs_write_data(bs, ptr->textName, pSize); /*Font name*/
510
0
  } else {
511
0
    gf_bs_write_u8(bs, 0);
512
0
  }
513
0
  return GF_OK;
514
0
}
515
516
GF_Err tx3g_box_size(GF_Box *s)
517
0
{
518
  /*base + this  + box + style*/
519
0
  s->size += 18 + GPP_BOX_SIZE + GPP_STYLE_SIZE;
520
0
  return GF_OK;
521
0
}
522
523
GF_Err text_box_size(GF_Box *s)
524
0
{
525
0
  GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s;
526
527
0
  s->size += 8;
528
  /*base + this + string length*/
529
0
  s->size += 43 + 1;
530
0
  if (ptr->textName)
531
0
    s->size += strlen(ptr->textName);
532
0
  return GF_OK;
533
0
}
534
535
#endif
536
537
GF_Box *styl_box_new()
538
2.17k
{
539
2.17k
  ISOM_DECL_BOX_ALLOC(GF_TextStyleBox, GF_ISOM_BOX_TYPE_STYL);
540
2.17k
  return (GF_Box *) tmp;
541
2.17k
}
542
543
void styl_box_del(GF_Box *s)
544
2.17k
{
545
2.17k
  GF_TextStyleBox*ptr = (GF_TextStyleBox*)s;
546
2.17k
  if (ptr->styles) gf_free(ptr->styles);
547
2.17k
  gf_free(ptr);
548
2.17k
}
549
550
GF_Err styl_box_read(GF_Box *s, GF_BitStream *bs)
551
1.30k
{
552
1.30k
  u32 i;
553
1.30k
  GF_TextStyleBox*ptr = (GF_TextStyleBox*)s;
554
1.30k
  ISOM_DECREASE_SIZE(ptr, 2);
555
1.25k
  ptr->entry_count = gf_bs_read_u16(bs);
556
557
1.25k
  if (ptr->size / GPP_STYLE_SIZE < ptr->entry_count)
558
559
    return GF_ISOM_INVALID_FILE;
559
560
697
  if (ptr->entry_count) {
561
412
    ptr->styles = (GF_StyleRecord*)gf_malloc(sizeof(GF_StyleRecord)*ptr->entry_count);
562
412
    if (!ptr->styles) return GF_OUT_OF_MEM;
563
2.16k
    for (i=0; i<ptr->entry_count; i++) {
564
1.75k
      ISOM_DECREASE_SIZE(ptr, GPP_STYLE_SIZE);
565
1.75k
      gpp_read_style(bs, &ptr->styles[i]);
566
1.75k
    }
567
412
  }
568
697
  return GF_OK;
569
697
}
570
571
#ifndef GPAC_DISABLE_ISOM_WRITE
572
GF_Err styl_box_write(GF_Box *s, GF_BitStream *bs)
573
486
{
574
486
  GF_Err e;
575
486
  u32 i;
576
486
  GF_TextStyleBox*ptr = (GF_TextStyleBox*)s;
577
486
  e = gf_isom_box_write_header(s, bs);
578
486
  if (e) return e;
579
580
486
  gf_bs_write_u16(bs, ptr->entry_count);
581
11.2k
  for (i=0; i<ptr->entry_count; i++) gpp_write_style(bs, &ptr->styles[i]);
582
486
  return GF_OK;
583
486
}
584
585
GF_Err styl_box_size(GF_Box *s)
586
972
{
587
972
  GF_TextStyleBox*ptr = (GF_TextStyleBox*)s;
588
589
972
  s->size += 2 + ptr->entry_count * GPP_STYLE_SIZE;
590
972
  return GF_OK;
591
972
}
592
593
#endif /*GPAC_DISABLE_ISOM_WRITE*/
594
595
GF_Box *hlit_box_new()
596
353
{
597
353
  ISOM_DECL_BOX_ALLOC(GF_TextHighlightBox, GF_ISOM_BOX_TYPE_HLIT);
598
353
  return (GF_Box *) tmp;
599
353
}
600
601
void hlit_box_del(GF_Box *s)
602
353
{
603
353
  gf_free(s);
604
353
}
605
606
GF_Err hlit_box_read(GF_Box *s, GF_BitStream *bs)
607
353
{
608
353
  GF_TextHighlightBox *ptr = (GF_TextHighlightBox *)s;
609
353
  ISOM_DECREASE_SIZE(ptr, 4)
610
274
  ptr->startcharoffset = gf_bs_read_u16(bs);
611
274
  ptr->endcharoffset = gf_bs_read_u16(bs);
612
274
  return GF_OK;
613
353
}
614
615
#ifndef GPAC_DISABLE_ISOM_WRITE
616
GF_Err hlit_box_write(GF_Box *s, GF_BitStream *bs)
617
0
{
618
0
  GF_Err e;
619
0
  GF_TextHighlightBox *ptr = (GF_TextHighlightBox *)s;
620
0
  e = gf_isom_box_write_header(s, bs);
621
0
  if (e) return e;
622
0
  gf_bs_write_u16(bs, ptr->startcharoffset);
623
0
  gf_bs_write_u16(bs, ptr->endcharoffset);
624
0
  return GF_OK;
625
0
}
626
627
GF_Err hlit_box_size(GF_Box *s)
628
0
{
629
0
  s->size += 4;
630
0
  return GF_OK;
631
0
}
632
633
#endif /*GPAC_DISABLE_ISOM_WRITE*/
634
635
GF_Box *hclr_box_new()
636
325
{
637
325
  ISOM_DECL_BOX_ALLOC(GF_TextHighlightColorBox, GF_ISOM_BOX_TYPE_HCLR);
638
325
  return (GF_Box *) tmp;
639
325
}
640
641
void hclr_box_del(GF_Box *s)
642
325
{
643
325
  gf_free(s);
644
325
}
645
646
GF_Err hclr_box_read(GF_Box *s, GF_BitStream *bs)
647
325
{
648
325
  GF_TextHighlightColorBox*ptr = (GF_TextHighlightColorBox*)s;
649
325
  ISOM_DECREASE_SIZE(ptr, 4)
650
166
  ptr->hil_color = gpp_read_rgba(bs);
651
166
  return GF_OK;
652
325
}
653
654
#ifndef GPAC_DISABLE_ISOM_WRITE
655
GF_Err hclr_box_write(GF_Box *s, GF_BitStream *bs)
656
0
{
657
0
  GF_Err e;
658
0
  GF_TextHighlightColorBox*ptr = (GF_TextHighlightColorBox*)s;
659
0
  e = gf_isom_box_write_header(s, bs);
660
0
  if (e) return e;
661
0
  gpp_write_rgba(bs, ptr->hil_color);
662
0
  return GF_OK;
663
0
}
664
665
GF_Err hclr_box_size(GF_Box *s)
666
0
{
667
0
  s->size += 4;
668
0
  return GF_OK;
669
0
}
670
671
#endif /*GPAC_DISABLE_ISOM_WRITE*/
672
673
GF_Box *krok_box_new()
674
816
{
675
816
  ISOM_DECL_BOX_ALLOC(GF_TextKaraokeBox, GF_ISOM_BOX_TYPE_KROK);
676
816
  return (GF_Box *) tmp;
677
816
}
678
679
void krok_box_del(GF_Box *s)
680
816
{
681
816
  GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s;
682
816
  if (ptr->records) gf_free(ptr->records);
683
816
  gf_free(ptr);
684
816
}
685
686
GF_Err krok_box_read(GF_Box *s, GF_BitStream *bs)
687
816
{
688
816
  GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s;
689
690
816
  ISOM_DECREASE_SIZE(ptr, 6)
691
590
  ptr->highlight_starttime = gf_bs_read_u32(bs);
692
590
  ptr->nb_entries = gf_bs_read_u16(bs);
693
590
  if (ptr->size / 8 < ptr->nb_entries)
694
214
    return GF_ISOM_INVALID_FILE;
695
696
376
  if (ptr->nb_entries) {
697
90
    u32 i;
698
90
    ptr->records = (KaraokeRecord*)gf_malloc(sizeof(KaraokeRecord)*ptr->nb_entries);
699
90
    if (!ptr->records) return GF_OUT_OF_MEM;
700
1.37k
    for (i=0; i<ptr->nb_entries; i++) {
701
1.28k
      ISOM_DECREASE_SIZE(ptr, 8)
702
1.28k
      ptr->records[i].highlight_endtime = gf_bs_read_u32(bs);
703
1.28k
      ptr->records[i].start_charoffset = gf_bs_read_u16(bs);
704
1.28k
      ptr->records[i].end_charoffset = gf_bs_read_u16(bs);
705
1.28k
    }
706
90
  }
707
376
  return GF_OK;
708
376
}
709
710
#ifndef GPAC_DISABLE_ISOM_WRITE
711
GF_Err krok_box_write(GF_Box *s, GF_BitStream *bs)
712
0
{
713
0
  GF_Err e;
714
0
  u32 i;
715
0
  GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s;
716
0
  e = gf_isom_box_write_header(s, bs);
717
0
  if (e) return e;
718
719
0
  gf_bs_write_u32(bs, ptr->highlight_starttime);
720
0
  gf_bs_write_u16(bs, ptr->nb_entries);
721
0
  for (i=0; i<ptr->nb_entries; i++) {
722
0
    gf_bs_write_u32(bs, ptr->records[i].highlight_endtime);
723
0
    gf_bs_write_u16(bs, ptr->records[i].start_charoffset);
724
0
    gf_bs_write_u16(bs, ptr->records[i].end_charoffset);
725
0
  }
726
0
  return GF_OK;
727
0
}
728
729
GF_Err krok_box_size(GF_Box *s)
730
0
{
731
0
  GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s;
732
0
  s->size += 6 + 8*ptr->nb_entries;
733
0
  return GF_OK;
734
0
}
735
736
#endif /*GPAC_DISABLE_ISOM_WRITE*/
737
738
GF_Box *dlay_box_new()
739
301
{
740
301
  ISOM_DECL_BOX_ALLOC(GF_TextScrollDelayBox, GF_ISOM_BOX_TYPE_DLAY);
741
301
  return (GF_Box *) tmp;
742
301
}
743
744
void dlay_box_del(GF_Box *s)
745
301
{
746
301
  gf_free(s);
747
301
}
748
749
GF_Err dlay_box_read(GF_Box *s, GF_BitStream *bs)
750
300
{
751
300
  GF_TextScrollDelayBox*ptr = (GF_TextScrollDelayBox*)s;
752
300
  ISOM_DECREASE_SIZE(ptr, 4)
753
87
  ptr->scroll_delay = gf_bs_read_u32(bs);
754
87
  return GF_OK;
755
300
}
756
757
#ifndef GPAC_DISABLE_ISOM_WRITE
758
GF_Err dlay_box_write(GF_Box *s, GF_BitStream *bs)
759
0
{
760
0
  GF_Err e;
761
0
  GF_TextScrollDelayBox*ptr = (GF_TextScrollDelayBox*)s;
762
0
  e = gf_isom_box_write_header(s, bs);
763
0
  if (e) return e;
764
0
  gf_bs_write_u32(bs, ptr->scroll_delay);
765
0
  return GF_OK;
766
0
}
767
768
GF_Err dlay_box_size(GF_Box *s)
769
0
{
770
0
  s->size += 4;
771
0
  return GF_OK;
772
0
}
773
774
#endif /*GPAC_DISABLE_ISOM_WRITE*/
775
776
GF_Box *href_box_new()
777
2.19k
{
778
2.19k
  ISOM_DECL_BOX_ALLOC(GF_TextHyperTextBox, GF_ISOM_BOX_TYPE_HREF);
779
2.19k
  return (GF_Box *) tmp;
780
2.19k
}
781
782
void href_box_del(GF_Box *s)
783
2.19k
{
784
2.19k
  GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s;
785
2.19k
  if (ptr->URL) gf_free(ptr->URL);
786
2.19k
  if (ptr->URL_hint) gf_free(ptr->URL_hint);
787
2.19k
  gf_free(ptr);
788
2.19k
}
789
790
GF_Err href_box_read(GF_Box *s, GF_BitStream *bs)
791
2.19k
{
792
2.19k
  u32 len;
793
2.19k
  GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s;
794
2.19k
  ISOM_DECREASE_SIZE(ptr, 6) //including 2 length fields
795
1.98k
  ptr->startcharoffset = gf_bs_read_u16(bs);
796
1.98k
  ptr->endcharoffset = gf_bs_read_u16(bs);
797
1.98k
  len = gf_bs_read_u8(bs);
798
1.98k
  if (len) {
799
1.41k
    ISOM_DECREASE_SIZE(ptr, len)
800
333
    ptr->URL = (char *) gf_malloc(sizeof(char) * (len+1));
801
333
    if (!ptr->URL) return GF_OUT_OF_MEM;
802
333
    gf_bs_read_data(bs, ptr->URL, len);
803
333
    ptr->URL[len] = 0;
804
333
  }
805
911
  len = gf_bs_read_u8(bs);
806
911
  if (len) {
807
642
    ISOM_DECREASE_SIZE(ptr, len)
808
222
    ptr->URL_hint = (char *) gf_malloc(sizeof(char) * (len+1));
809
222
    if (!ptr->URL_hint) return GF_OUT_OF_MEM;
810
222
    gf_bs_read_data(bs, ptr->URL_hint, len);
811
222
    ptr->URL_hint[len]= 0;
812
222
  }
813
491
  return GF_OK;
814
911
}
815
816
#ifndef GPAC_DISABLE_ISOM_WRITE
817
GF_Err href_box_write(GF_Box *s, GF_BitStream *bs)
818
0
{
819
0
  u32 len;
820
0
  GF_Err e;
821
0
  GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s;
822
0
  e = gf_isom_box_write_header(s, bs);
823
0
  if (e) return e;
824
825
0
  gf_bs_write_u16(bs, ptr->startcharoffset);
826
0
  gf_bs_write_u16(bs, ptr->endcharoffset);
827
0
  if (ptr->URL) {
828
0
    len = (u32) strlen(ptr->URL);
829
0
    gf_bs_write_u8(bs, len);
830
0
    gf_bs_write_data(bs, ptr->URL, len);
831
0
  } else {
832
0
    gf_bs_write_u8(bs, 0);
833
0
  }
834
0
  if (ptr->URL_hint) {
835
0
    len = (u32) strlen(ptr->URL_hint);
836
0
    gf_bs_write_u8(bs, len);
837
0
    gf_bs_write_data(bs, ptr->URL_hint, len);
838
0
  } else {
839
0
    gf_bs_write_u8(bs, 0);
840
0
  }
841
0
  return GF_OK;
842
0
}
843
844
GF_Err href_box_size(GF_Box *s)
845
0
{
846
0
  GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s;
847
0
  s->size += 6;
848
0
  if (ptr->URL) s->size += strlen(ptr->URL);
849
0
  if (ptr->URL_hint) s->size += strlen(ptr->URL_hint);
850
0
  return GF_OK;
851
0
}
852
853
#endif /*GPAC_DISABLE_ISOM_WRITE*/
854
855
856
GF_Box *tbox_box_new()
857
272
{
858
272
  ISOM_DECL_BOX_ALLOC(GF_TextBoxBox, GF_ISOM_BOX_TYPE_TBOX);
859
272
  return (GF_Box *) tmp;
860
272
}
861
862
void tbox_box_del(GF_Box *s)
863
272
{
864
272
  gf_free(s);
865
272
}
866
867
GF_Err tbox_box_read(GF_Box *s, GF_BitStream *bs)
868
270
{
869
270
  GF_TextBoxBox*ptr = (GF_TextBoxBox*)s;
870
270
  ISOM_DECREASE_SIZE(ptr, GPP_BOX_SIZE)
871
188
  gpp_read_box(bs, &ptr->box);
872
188
  return GF_OK;
873
270
}
874
875
#ifndef GPAC_DISABLE_ISOM_WRITE
876
GF_Err tbox_box_write(GF_Box *s, GF_BitStream *bs)
877
0
{
878
0
  GF_Err e;
879
0
  GF_TextBoxBox*ptr = (GF_TextBoxBox*)s;
880
0
  e = gf_isom_box_write_header(s, bs);
881
0
  if (e) return e;
882
0
  gpp_write_box(bs, &ptr->box);
883
0
  return GF_OK;
884
0
}
885
886
GF_Err tbox_box_size(GF_Box *s)
887
0
{
888
0
  s->size += 8;
889
0
  return GF_OK;
890
0
}
891
892
#endif /*GPAC_DISABLE_ISOM_WRITE*/
893
894
895
GF_Box *blnk_box_new()
896
388
{
897
388
  ISOM_DECL_BOX_ALLOC(GF_TextBlinkBox, GF_ISOM_BOX_TYPE_BLNK);
898
388
  return (GF_Box *) tmp;
899
388
}
900
901
void blnk_box_del(GF_Box *s)
902
388
{
903
388
  gf_free(s);
904
388
}
905
906
GF_Err blnk_box_read(GF_Box *s, GF_BitStream *bs)
907
388
{
908
388
  GF_TextBlinkBox*ptr = (GF_TextBlinkBox*)s;
909
388
  ISOM_DECREASE_SIZE(ptr, 4)
910
313
  ptr->startcharoffset = gf_bs_read_u16(bs);
911
313
  ptr->endcharoffset = gf_bs_read_u16(bs);
912
313
  return GF_OK;
913
388
}
914
915
#ifndef GPAC_DISABLE_ISOM_WRITE
916
GF_Err blnk_box_write(GF_Box *s, GF_BitStream *bs)
917
0
{
918
0
  GF_Err e;
919
0
  GF_TextBlinkBox*ptr = (GF_TextBlinkBox*)s;
920
0
  e = gf_isom_box_write_header(s, bs);
921
0
  if (e) return e;
922
0
  gf_bs_write_u16(bs, ptr->startcharoffset);
923
0
  gf_bs_write_u16(bs, ptr->endcharoffset);
924
0
  return GF_OK;
925
0
}
926
927
GF_Err blnk_box_size(GF_Box *s)
928
0
{
929
0
  s->size += 4;
930
0
  return GF_OK;
931
0
}
932
933
#endif /*GPAC_DISABLE_ISOM_WRITE*/
934
935
GF_Box *twrp_box_new()
936
476
{
937
476
  ISOM_DECL_BOX_ALLOC(GF_TextWrapBox, GF_ISOM_BOX_TYPE_TWRP);
938
476
  return (GF_Box *) tmp;
939
476
}
940
941
void twrp_box_del(GF_Box *s)
942
476
{
943
476
  gf_free(s);
944
476
}
945
946
GF_Err twrp_box_read(GF_Box *s, GF_BitStream *bs)
947
476
{
948
476
  GF_TextWrapBox*ptr = (GF_TextWrapBox*)s;
949
476
  ISOM_DECREASE_SIZE(ptr, 1)
950
124
  ptr->wrap_flag = gf_bs_read_u8(bs);
951
124
  return GF_OK;
952
476
}
953
954
#ifndef GPAC_DISABLE_ISOM_WRITE
955
GF_Err twrp_box_write(GF_Box *s, GF_BitStream *bs)
956
0
{
957
0
  GF_Err e;
958
0
  GF_TextWrapBox*ptr = (GF_TextWrapBox*)s;
959
0
  e = gf_isom_box_write_header(s, bs);
960
0
  if (e) return e;
961
0
  gf_bs_write_u8(bs, ptr->wrap_flag);
962
0
  return GF_OK;
963
0
}
964
GF_Err twrp_box_size(GF_Box *s)
965
0
{
966
0
  s->size += 1;
967
0
  return GF_OK;
968
0
}
969
970
#endif /*GPAC_DISABLE_ISOM_WRITE*/
971
972
void tsel_box_del(GF_Box *s)
973
1.25k
{
974
1.25k
  GF_TrackSelectionBox *ptr;
975
1.25k
  ptr = (GF_TrackSelectionBox *) s;
976
1.25k
  if (ptr == NULL) return;
977
1.25k
  if (ptr->attributeList) gf_free(ptr->attributeList);
978
1.25k
  gf_free(ptr);
979
1.25k
}
980
981
GF_Err tsel_box_read(GF_Box *s,GF_BitStream *bs)
982
1.25k
{
983
1.25k
  u32 i;
984
1.25k
  GF_TrackSelectionBox *ptr = (GF_TrackSelectionBox *) s;
985
986
1.25k
  ISOM_DECREASE_SIZE(ptr, 4);
987
696
  ptr->switchGroup = gf_bs_read_u32(bs);
988
989
696
  if (ptr->size % 4) return GF_ISOM_INVALID_FILE;
990
420
  ptr->attributeListCount = (u32)ptr->size/4;
991
420
  ptr->attributeList = gf_malloc(ptr->attributeListCount*sizeof(u32));
992
420
  if (ptr->attributeList == NULL) return GF_OUT_OF_MEM;
993
994
15.1k
  for (i=0; i< ptr->attributeListCount; i++) {
995
14.7k
    ptr->attributeList[i] = gf_bs_read_u32(bs);
996
14.7k
  }
997
420
  return GF_OK;
998
420
}
999
1000
GF_Box *tsel_box_new()
1001
1.25k
{
1002
1.25k
  ISOM_DECL_BOX_ALLOC(GF_TrackSelectionBox, GF_ISOM_BOX_TYPE_TSEL);
1003
1.25k
  return (GF_Box *)tmp;
1004
1.25k
}
1005
1006
1007
#ifndef GPAC_DISABLE_ISOM_WRITE
1008
1009
GF_Err tsel_box_write(GF_Box *s, GF_BitStream *bs)
1010
0
{
1011
0
  GF_Err e;
1012
0
  u32 i;
1013
0
  GF_TrackSelectionBox *ptr = (GF_TrackSelectionBox *) s;
1014
1015
0
  e = gf_isom_full_box_write(s, bs);
1016
0
  if (e) return e;
1017
0
  gf_bs_write_u32(bs,ptr->switchGroup);
1018
1019
0
  for (i = 0; i < ptr->attributeListCount; i++ ) {
1020
0
    gf_bs_write_u32(bs, ptr->attributeList[i]);
1021
0
  }
1022
1023
0
  return GF_OK;
1024
0
}
1025
1026
GF_Err tsel_box_size(GF_Box *s)
1027
0
{
1028
0
  GF_TrackSelectionBox *ptr = (GF_TrackSelectionBox *) s;
1029
0
  ptr->size += 4 + (4*ptr->attributeListCount);
1030
0
  return GF_OK;
1031
0
}
1032
1033
#endif /*GPAC_DISABLE_ISOM_WRITE*/
1034
1035
1036
GF_Box *dimC_box_new()
1037
1.43k
{
1038
1.43k
  ISOM_DECL_BOX_ALLOC(GF_DIMSSceneConfigBox, GF_ISOM_BOX_TYPE_DIMC);
1039
1.43k
  return (GF_Box *)tmp;
1040
1.43k
}
1041
void dimC_box_del(GF_Box *s)
1042
1.43k
{
1043
1.43k
  GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s;
1044
1.43k
  if (p->contentEncoding) gf_free(p->contentEncoding);
1045
1.43k
  if (p->textEncoding) gf_free(p->textEncoding);
1046
1.43k
  gf_free(p);
1047
1.43k
}
1048
1049
GF_Err dimC_box_read(GF_Box *s, GF_BitStream *bs)
1050
1.43k
{
1051
1.43k
  GF_Err e;
1052
1.43k
  u32 i, msize;
1053
1.43k
  GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s;
1054
1055
1.43k
  ISOM_DECREASE_SIZE(p, 3);
1056
1.08k
  p->profile = gf_bs_read_u8(bs);
1057
1.08k
  p->level = gf_bs_read_u8(bs);
1058
1.08k
  p->pathComponents = gf_bs_read_int(bs, 4);
1059
1.08k
  p->fullRequestHost = gf_bs_read_int(bs, 1);
1060
1.08k
  p->streamType = gf_bs_read_int(bs, 1);
1061
1.08k
  p->containsRedundant = gf_bs_read_int(bs, 2);
1062
1063
1.08k
  char *str = gf_malloc( (size_t) (p->size+1));
1064
1.08k
  if (!str) return GF_OUT_OF_MEM;
1065
1.08k
  msize = (u32) p->size;
1066
1.08k
  str[msize] = 0;
1067
1.08k
  i=0;
1068
1.08k
  str[0]=0;
1069
10.4k
  while (i < msize) {
1070
9.91k
    ISOM_DECREASE_SIZE_GOTO_EXIT(p, 1);
1071
9.91k
    str[i] = gf_bs_read_u8(bs);
1072
9.91k
    if (!str[i]) break;
1073
9.39k
    i++;
1074
9.39k
  }
1075
1.08k
  if (i == msize) {
1076
567
    gf_free(str);
1077
567
    return GF_ISOM_INVALID_FILE;
1078
567
  }
1079
1080
517
  p->textEncoding = gf_strdup(str);
1081
1082
517
  i=0;
1083
517
  str[0]=0;
1084
1.75k
  while (i < msize) {
1085
1.75k
    ISOM_DECREASE_SIZE_GOTO_EXIT(p, 1);
1086
1.53k
    str[i] = gf_bs_read_u8(bs);
1087
1.53k
    if (!str[i]) break;
1088
1.23k
    i++;
1089
1.23k
  }
1090
296
  if (i == msize) {
1091
0
    gf_free(str);
1092
0
    return GF_ISOM_INVALID_FILE;
1093
0
  }
1094
1095
296
  p->contentEncoding = gf_strdup(str);
1096
296
  gf_free(str);
1097
296
  if (!p->textEncoding || !p->contentEncoding)
1098
0
    return GF_OUT_OF_MEM;
1099
296
  return GF_OK;
1100
1101
221
exit:
1102
221
  gf_free(str);
1103
221
  return e;
1104
296
}
1105
1106
#ifndef GPAC_DISABLE_ISOM_WRITE
1107
GF_Err dimC_box_write(GF_Box *s, GF_BitStream *bs)
1108
0
{
1109
0
  GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s;
1110
0
  GF_Err e = gf_isom_box_write_header(s, bs);
1111
0
  if (e) return e;
1112
0
  gf_bs_write_u8(bs, p->profile);
1113
0
  gf_bs_write_u8(bs, p->level);
1114
0
  gf_bs_write_int(bs, p->pathComponents, 4);
1115
0
  gf_bs_write_int(bs, p->fullRequestHost, 1);
1116
0
  gf_bs_write_int(bs, p->streamType, 1);
1117
0
  gf_bs_write_int(bs, p->containsRedundant, 2);
1118
0
  if (p->textEncoding)
1119
0
    gf_bs_write_data(bs, p->textEncoding, (u32) strlen(p->textEncoding));
1120
0
  gf_bs_write_u8(bs, 0);
1121
0
  if (p->contentEncoding)
1122
0
    gf_bs_write_data(bs, p->contentEncoding, (u32) strlen(p->contentEncoding));
1123
0
  gf_bs_write_u8(bs, 0);
1124
0
  return GF_OK;
1125
0
}
1126
GF_Err dimC_box_size(GF_Box *s)
1127
0
{
1128
0
  GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s;
1129
0
  s->size += 3 + 2;
1130
0
  if (p->textEncoding) s->size += strlen(p->textEncoding);
1131
0
  if (p->contentEncoding) s->size += strlen(p->contentEncoding);
1132
0
  return GF_OK;
1133
0
}
1134
#endif /*GPAC_DISABLE_ISOM_WRITE*/
1135
1136
1137
1138
GF_Box *diST_box_new()
1139
1.21k
{
1140
1.21k
  ISOM_DECL_BOX_ALLOC(GF_DIMSScriptTypesBox, GF_ISOM_BOX_TYPE_DIST);
1141
1.21k
  return (GF_Box *)tmp;
1142
1.21k
}
1143
void diST_box_del(GF_Box *s)
1144
1.21k
{
1145
1.21k
  GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s;
1146
1.21k
  if (p->content_script_types) gf_free(p->content_script_types);
1147
1.21k
  gf_free(p);
1148
1.21k
}
1149
1150
GF_Err diST_box_read(GF_Box *s, GF_BitStream *bs)
1151
790
{
1152
790
  GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s;
1153
1154
790
  p->content_script_types = gf_malloc(sizeof(u8) * ((u32) s->size + 1));
1155
790
  if (!p->content_script_types) return GF_OUT_OF_MEM;
1156
790
  gf_bs_read_data(bs, p->content_script_types, (u32) s->size);
1157
790
  p->content_script_types[s->size] = 0;
1158
790
  return GF_OK;
1159
790
}
1160
1161
#ifndef GPAC_DISABLE_ISOM_WRITE
1162
GF_Err diST_box_write(GF_Box *s, GF_BitStream *bs)
1163
0
{
1164
0
  GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s;
1165
0
  GF_Err e = gf_isom_box_write_header(s, bs);
1166
0
  if (e) return e;
1167
0
  if (p->content_script_types)
1168
0
    gf_bs_write_data(bs, p->content_script_types, (u32) strlen(p->content_script_types)+1);
1169
0
  else
1170
0
    gf_bs_write_u8(bs, 0);
1171
0
  return GF_OK;
1172
0
}
1173
GF_Err diST_box_size(GF_Box *s)
1174
0
{
1175
0
  GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s;
1176
0
  s->size += p->content_script_types ? (strlen(p->content_script_types)+1) : 1;
1177
0
  return GF_OK;
1178
0
}
1179
#endif /*GPAC_DISABLE_ISOM_WRITE*/
1180
1181
1182
GF_Box *dims_box_new()
1183
1.71k
{
1184
1.71k
  ISOM_DECL_BOX_ALLOC(GF_DIMSSampleEntryBox, GF_ISOM_BOX_TYPE_DIMS);
1185
1.71k
  gf_isom_sample_entry_init((GF_SampleEntryBox *)tmp);
1186
1.71k
  return (GF_Box*)tmp;
1187
1.71k
}
1188
void dims_box_del(GF_Box *s)
1189
1.71k
{
1190
1.71k
  gf_isom_sample_entry_predestroy((GF_SampleEntryBox *)s);
1191
1.71k
  gf_free(s);
1192
1.71k
}
1193
1194
GF_Err dims_on_child_box(GF_Box *s, GF_Box *a, Bool is_rem)
1195
1.79k
{
1196
1.79k
  GF_DIMSSampleEntryBox *ptr = (GF_DIMSSampleEntryBox  *)s;
1197
1.79k
  switch (a->type) {
1198
286
  case GF_ISOM_BOX_TYPE_DIMC:
1199
286
    BOX_FIELD_ASSIGN(config, GF_DIMSSceneConfigBox)
1200
265
    break;
1201
776
  case GF_ISOM_BOX_TYPE_DIST:
1202
776
    BOX_FIELD_ASSIGN(scripts, GF_DIMSScriptTypesBox)
1203
541
    break;
1204
1.79k
  }
1205
1.53k
  return GF_OK;
1206
1.79k
}
1207
GF_Err dims_box_read(GF_Box *s, GF_BitStream *bs)
1208
1.71k
{
1209
1.71k
  GF_Err e;
1210
1.71k
  GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s;
1211
1212
1.71k
  e = gf_isom_base_sample_entry_read((GF_SampleEntryBox *)p, bs);
1213
1.71k
  if (e) return e;
1214
1215
1.71k
  ISOM_DECREASE_SIZE(p, 8);
1216
1.46k
  return gf_isom_box_array_read(s, bs);
1217
1.71k
}
1218
1219
#ifndef GPAC_DISABLE_ISOM_WRITE
1220
GF_Err dims_box_write(GF_Box *s, GF_BitStream *bs)
1221
0
{
1222
0
  GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s;
1223
0
  GF_Err e = gf_isom_box_write_header(s, bs);
1224
0
  if (e) return e;
1225
0
  gf_bs_write_data(bs, p->reserved, 6);
1226
0
  gf_bs_write_u16(bs, p->dataReferenceIndex);
1227
0
  return GF_OK;
1228
0
}
1229
1230
GF_Err dims_box_size(GF_Box *s)
1231
0
{
1232
0
  u32 pos = 0;
1233
0
  GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s;
1234
0
  s->size += 8;
1235
0
  gf_isom_check_position(s, (GF_Box *) p->config, &pos);
1236
0
  gf_isom_check_position(s, (GF_Box *) p->scripts, &pos);
1237
0
  return GF_OK;
1238
0
}
1239
#endif /*GPAC_DISABLE_ISOM_WRITE*/
1240
1241
#endif /*GPAC_DISABLE_ISOM*/