/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*/ |