~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to gt/gt.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-25 15:47:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080225154712-qvr11ekcea4c9ry8
Tags: 1.1.6-0.1ubuntu1
* Merge from debian-multimedia (LP: #120003), Ubuntu Changes:
 - For ffmpeg-related build-deps, remove cvs from package names.
 - Standards-Version 3.7.3
 - Maintainer Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * gt.c
3
 
 * GnuTime module
4
 
 *
5
 
 * Copyright (C) 1998,99 Rasca, Berlin
6
 
 * EMail: thron@gmx.de
7
 
 *
8
 
 * This library is free software; you can redistribute it and/or
9
 
 * modify it under the terms of the GNU Library General Public
10
 
 * License as published by the Free Software Foundation; either
11
 
 * version 2 of the License, or (at your option) any later version.
12
 
 *
13
 
 * This library is distributed in the hope that it will be useful,
14
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 
 * Library General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU Library General Public
19
 
 * License along with this library; if not, write to the Free Software
20
 
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 
 */
22
 
 
23
 
#include <stdio.h>
24
 
#include <stdlib.h>
25
 
#include <time.h>
26
 
#include "gt.h"
27
 
 
28
 
/*
29
 
 * alloc space for a named atom, the following integer allocs space:
30
 
 *   for container atoms some space for pointers to subatoms
31
 
 *   for leaf atoms it depends on the atom type, e.g. some space for tab entries
32
 
 */
33
 
void *
34
 
gt_alloc_atom (int type, int nmb)
35
 
{
36
 
        gt_atom *p;
37
 
        int size = 8, mem = sizeof(gt_atom);
38
 
        int is_cont = 0;
39
 
 
40
 
        switch (type) {
41
 
                /* container atoms */
42
 
                case GTA_movie:
43
 
                case GTA_track:
44
 
                case GTA_media:
45
 
                case GTA_media_info:
46
 
                case GTA_data_info:
47
 
                case GTA_sample_table:
48
 
                case GTA_edit:
49
 
                case GTA_base_media_header:
50
 
                        mem += sizeof(gt_atom*) * nmb;
51
 
                        is_cont = 1;
52
 
                        break;
53
 
                /* leaf atoms */
54
 
                case GTA_movie_header:
55
 
                        mem = sizeof (gt_mvhd_atom);
56
 
                        size = 108;
57
 
                        break;
58
 
                case GTA_movie_data:
59
 
                        mem = sizeof (mdat_atom) + nmb;
60
 
                        size = 8 + nmb;
61
 
                        break;
62
 
                case GTA_track_header:
63
 
                        mem = sizeof (gt_tkhd_atom);
64
 
                        size = 92;
65
 
                        break;
66
 
                case GTA_media_header:
67
 
                        mem = sizeof (gt_mdhd_atom);
68
 
                        size = 32;
69
 
                        break;
70
 
                case GTA_handler_ref:
71
 
                        mem = sizeof (gt_hdlr_atom) + nmb + 2;
72
 
                        size = 32 + nmb + 1;
73
 
                        break;
74
 
                case GTA_video_media_header:
75
 
                case GTA_sound_media_header:
76
 
                        mem = sizeof (gt_vmhd_atom);
77
 
                        size = 20;
78
 
                        break;
79
 
                case GTA_base_media_info:
80
 
                        mem = sizeof (gt_gmin_atom);
81
 
                        size = 24;
82
 
                        break;
83
 
                case GTA_data_ref:
84
 
                        mem = sizeof (gt_dref_atom) + nmb * sizeof(gt_dref_entry);
85
 
                        size = 16 + nmb * 12;
86
 
                        break;
87
 
                case GTA_sample_desc:
88
 
                        mem = sizeof (gt_stsd_atom) + nmb * sizeof (gt_stsd_entry);
89
 
                        size = 16 + nmb * 86;
90
 
                        break;
91
 
                case GTA_time_to_sample:
92
 
                        mem = sizeof (gt_stts_atom) + nmb * sizeof(gt_stts_entry);
93
 
                        size = 16 + nmb * 8;
94
 
                        break;
95
 
                case GTA_sample_size:
96
 
                        mem = sizeof (gt_stsz_atom) + nmb * sizeof (gt_stsz_entry);
97
 
                        size = 20 + nmb * 4;
98
 
                        break;
99
 
                case GTA_sample_to_chunk:
100
 
                        mem = sizeof (gt_stsc_atom) + nmb * sizeof (gt_stsc_entry);
101
 
                        size = 16 + nmb * 12;
102
 
                        break;
103
 
                case GTA_chunk_offset:
104
 
                        mem = sizeof (gt_stco_atom) + nmb * sizeof (gt_stco_entry);
105
 
                        size = 16 + nmb * 4;
106
 
                        break;
107
 
                case GTA_free:
108
 
                        mem = sizeof (free_atom);
109
 
                        size = 8 + nmb;
110
 
                        break;
111
 
                case GTA_skip:
112
 
                        mem = sizeof (skip_atom);
113
 
                        size = 8 + nmb;
114
 
                        break;
115
 
                case GTA_user_data:
116
 
                        mem = sizeof (gt_udta_atom) + nmb * sizeof(gt_udta_entry);
117
 
                        size = 8 + 12 * nmb;    /* at least */
118
 
                        break;
119
 
                default:
120
 
                        fprintf (stderr, "gt_alloc_atom() unknown atom type: %X\n", type);
121
 
                        return (NULL);
122
 
                        break;
123
 
        }
124
 
        p = calloc (mem, 1);
125
 
        if (!p)
126
 
                return (NULL);
127
 
        p->size = size;
128
 
        p->type = type;
129
 
        if (is_cont && nmb) {
130
 
                p->suba = (gt_atom **)(p+1);
131
 
        } else if (nmb) {
132
 
                int i;
133
 
                switch (type) {
134
 
                        case GTA_movie_data:
135
 
                                ((mdat_atom *)p)->data = (char *)((mdat_atom*)p+1);
136
 
                                break;
137
 
                        case GTA_handler_ref:
138
 
                                ((gt_hdlr_atom *)p)->comp_name = (char*)((gt_hdlr_atom*)p+1);
139
 
                                break;
140
 
                        case GTA_data_ref:
141
 
                        case GTA_sample_desc:
142
 
                        case GTA_time_to_sample:
143
 
                        case GTA_sample_to_chunk:
144
 
                        case GTA_chunk_offset:
145
 
                                ((gt_dref_atom *)p)->tab = (void *)((gt_dref_atom*)p+1);
146
 
                                break;
147
 
                        case GTA_sample_size:
148
 
                                ((gt_stsz_atom *)p)->tab = (void *)((gt_stsz_atom*)p+1);
149
 
                                break;
150
 
                        case GTA_skip:
151
 
                                break;
152
 
                        case GTA_user_data:
153
 
                                ((gt_udta_atom *)p)->count = nmb;
154
 
                                for (i = 0; i < nmb; i++) {
155
 
                                        ((gt_udta_atom *)p)->tab[i] = (gt_udta_entry *)
156
 
                                                (((char *)p)+sizeof(gt_udta_atom) +
157
 
                                                i * sizeof(gt_udta_entry));
158
 
                                }
159
 
                                break;
160
 
                        default:
161
 
                                fprintf (stderr, "error in gt_alloc_atom(%x[%c%c%c%c], %d)\n",
162
 
                                        type, *((char *)&type)+3, *((char*)&type)+2,
163
 
                                                *((char *)&type+1), *((char*)&type), nmb);
164
 
                                break;
165
 
                }
166
 
        }
167
 
        return (p);
168
 
}
169
 
 
170
 
/*
171
 
 * free this and all subatoms
172
 
 */
173
 
void
174
 
gt_atom_free (gt_atom *atom)
175
 
{
176
 
        int i;
177
 
 
178
 
        if (!atom)
179
 
        return;
180
 
        if (GT_IS_CONTAINER(atom)) {
181
 
                for (i = 0; i < atom->memb; i++) {
182
 
                        gt_atom_free (atom->suba[i]);
183
 
                }
184
 
        } else {
185
 
                free (atom);
186
 
        }
187
 
}
188
 
 
189
 
 
190
 
/*
191
 
 * write movie header leaf atom
192
 
 */
193
 
int
194
 
write_mvhd_atom (gt_atom *a, FILE *fp)
195
 
{
196
 
        gt_mvhd_atom *m = (gt_mvhd_atom *)a;
197
 
        int rc = 0;
198
 
 
199
 
        if (m->size == 0)
200
 
                m->size = 108 /* sizeof (mvhd_atom) doesn't work cause of alignm? */;
201
 
        rc += gt_write4byte (m->size, fp);
202
 
        rc += gt_write4byte (m->type, fp);
203
 
        rc += fwrite (&m->version, 1, 1, fp);
204
 
        rc += fwrite (&m->flags, 1, 3, fp);
205
 
        rc += gt_write4byte (m->ctime, fp);
206
 
        rc += gt_write4byte (m->mtime, fp);
207
 
        rc += gt_write4byte (m->time_scale, fp);
208
 
        rc += gt_write4byte (m->duration, fp);
209
 
        rc += gt_write2byte (m->pref_rate.high, fp);
210
 
        rc += gt_write2byte (m->pref_rate.low, fp);
211
 
        rc += fwrite (&m->pref_volume.high, 1, 1, fp);
212
 
        rc += fwrite (&m->pref_volume.low, 1, 1, fp);
213
 
        rc += fwrite (&m->reserved, 1, 10, fp);
214
 
        rc += fwrite (&m->matrix, 1, 36, fp);
215
 
        rc += gt_write4byte (m->preview_time, fp);
216
 
        rc += gt_write4byte (m->preview_duration, fp);
217
 
        rc += gt_write4byte (m->poster_time, fp);
218
 
        rc += gt_write4byte (m->sel_time, fp);
219
 
        rc += gt_write4byte (m->sel_duration, fp);
220
 
        rc += gt_write4byte (m->current_time, fp);
221
 
        rc += gt_write4byte (m->next_track_id, fp);
222
 
        return (rc);
223
 
}
224
 
 
225
 
/*
226
 
 * write a free, skip or mdat atom
227
 
 */
228
 
int
229
 
write_mdat_atom (gt_atom *a, FILE *fp)
230
 
{
231
 
        mdat_atom *m = (mdat_atom *)a;
232
 
        int rc = 0;
233
 
 
234
 
        rc += gt_write4byte (m->size, fp);
235
 
        rc += gt_write4byte (m->type, fp);
236
 
        if ((m->type == GTA_free) || (m->type == GTA_skip)) {
237
 
                /* write fill bytes */
238
 
                int i;
239
 
                for (i = 0; i < m->size-8; i++) {
240
 
                        rc += fwrite ("\0", 1, 1, fp);
241
 
                }
242
 
        } else {
243
 
                rc += fwrite (m->data, 1, m->size-8, fp);
244
 
        }
245
 
        return (rc);
246
 
}
247
 
 
248
 
/*
249
 
 * write user data atom
250
 
 */
251
 
int
252
 
write_udta_atom (gt_atom *a, FILE *fp)
253
 
{
254
 
        gt_udta_atom *u = (gt_udta_atom *)a;
255
 
        int rc=0, i, j;
256
 
 
257
 
        if (u->type != GTA_user_data)
258
 
                return (0);
259
 
        if (u->size == 0) {
260
 
                u->size = 8;
261
 
        }
262
 
        rc += gt_write4byte (u->size, fp);
263
 
        rc += gt_write4byte (u->type, fp);
264
 
 
265
 
        for (i = 0; i < u->count; i++) {
266
 
                rc += gt_write4byte (u->tab[i]->size, fp);
267
 
                rc += gt_write4byte (u->tab[i]->type, fp);
268
 
                if (u->tab[i]->size > 12) {
269
 
                        rc += gt_write2byte (u->tab[i]->tlen, fp);
270
 
                        rc += gt_write2byte (u->tab[i]->lang, fp);
271
 
                        for (j = 0; j < u->tab[i]->tlen; j++) {
272
 
                                rc += fwrite (u->tab[i]->text+j, 1, 1, fp);
273
 
                        }
274
 
                } else if (u->tab[i]->size > 8) {
275
 
                        rc += gt_write4byte ((long)u->tab[i]->text, fp);
276
 
                }
277
 
        }
278
 
        return (rc);
279
 
}
280
 
 
281
 
/*
282
 
 * write track header leaf atom
283
 
 */
284
 
int
285
 
write_tkhd_atom (gt_atom *a, FILE *fp)
286
 
{
287
 
        gt_tkhd_atom *tkhd = (gt_tkhd_atom *)a;
288
 
        int rc = 0;
289
 
 
290
 
        if (tkhd->size == 0)
291
 
                tkhd->size = 92;
292
 
        rc += gt_write4byte (tkhd->size, fp);
293
 
        rc += gt_write4byte (tkhd->type, fp);
294
 
        rc += fwrite (&tkhd->version, 1, 1, fp);
295
 
        rc += fwrite (&tkhd->flags, 1, 3, fp);
296
 
        rc += gt_write4byte (tkhd->ctime, fp);
297
 
        rc += gt_write4byte (tkhd->mtime, fp);
298
 
        rc += gt_write4byte (tkhd->track_id, fp);
299
 
        rc += fwrite (&tkhd->reserved1, 1, 4, fp);
300
 
        rc += gt_write4byte (tkhd->duration, fp);
301
 
        rc += fwrite (&tkhd->reserved2, 1, 8, fp);
302
 
        rc += gt_write2byte (tkhd->layer, fp);
303
 
        rc += gt_write2byte (tkhd->alternate_group, fp);
304
 
        rc += fwrite (&tkhd->volume.high, 1, 1, fp);
305
 
        rc += fwrite (&tkhd->volume.low,  1, 1, fp);
306
 
        rc += fwrite (&tkhd->reserved3, 1, 2, fp);
307
 
        rc += fwrite (&tkhd->matrix, 1, 36, fp);
308
 
        rc += gt_write2byte (tkhd->width.high, fp);
309
 
        rc += gt_write2byte (tkhd->width.low, fp);
310
 
        rc += gt_write2byte (tkhd->height.high, fp);
311
 
        rc += gt_write2byte (tkhd->height.low, fp);
312
 
        return (rc);
313
 
}
314
 
 
315
 
/*
316
 
 * write media header leaf atom
317
 
 */
318
 
int
319
 
write_mdhd_atom (gt_atom *a, FILE *fp)
320
 
{
321
 
        gt_mdhd_atom *m = (gt_mdhd_atom *)a;
322
 
        int rc = 0;
323
 
 
324
 
        if (m->size == 0)
325
 
                m->size = sizeof (gt_mdhd_atom);
326
 
        rc += gt_write4byte (m->size, fp);
327
 
        rc += gt_write4byte (m->type, fp);
328
 
        rc += fwrite (&m->version, 1, 1, fp);
329
 
        rc += fwrite (&m->flags, 1, 3, fp);
330
 
        rc += gt_write4byte (m->ctime, fp);
331
 
        rc += gt_write4byte (m->mtime, fp);
332
 
        rc += gt_write4byte (m->time_scale, fp);
333
 
        rc += gt_write4byte (m->duration, fp);
334
 
        rc += gt_write2byte (m->language, fp);
335
 
        rc += gt_write2byte (m->quality, fp);
336
 
        return (rc);
337
 
}
338
 
 
339
 
/*
340
 
 * write video media information header leaf atom
341
 
 */
342
 
int
343
 
write_vmhd_atom (gt_atom *a, FILE *fp)
344
 
{
345
 
        gt_vmhd_atom *m = (gt_vmhd_atom *)a;
346
 
        int rc = 0;
347
 
 
348
 
        if (m->size == 0)
349
 
                m->size = sizeof (gt_vmhd_atom);
350
 
        rc += gt_write4byte (m->size, fp);
351
 
        rc += gt_write4byte (m->type, fp);
352
 
        rc += fwrite (&m->version, 1, 1, fp);
353
 
        rc += fwrite (&m->flags, 1, 3, fp);
354
 
        rc += gt_write2byte (m->grmode, fp);
355
 
        rc += gt_write2byte (m->opcolor[0], fp);
356
 
        rc += gt_write2byte (m->opcolor[1], fp);
357
 
        rc += gt_write2byte (m->opcolor[2], fp);
358
 
        return (rc);
359
 
}
360
 
 
361
 
/*
362
 
 * write video media information header leaf atom
363
 
 */
364
 
int
365
 
write_gmin_atom (gt_atom *a, FILE *fp)
366
 
{
367
 
        gt_gmin_atom *m = (gt_gmin_atom *)a;
368
 
        int rc = 0;
369
 
 
370
 
        if (m->size == 0)
371
 
                m->size = sizeof (gt_vmhd_atom);
372
 
        rc += gt_write4byte (m->size, fp);
373
 
        rc += gt_write4byte (m->type, fp);
374
 
        rc += fwrite (&m->version, 1, 1, fp);
375
 
        rc += fwrite (&m->flags, 1, 3, fp);
376
 
        rc += gt_write2byte (m->grmode, fp);
377
 
        rc += gt_write2byte (m->opcolor[0], fp);
378
 
        rc += gt_write2byte (m->opcolor[1], fp);
379
 
        rc += gt_write2byte (m->opcolor[2], fp);
380
 
        rc += gt_write2byte (m->balance, fp);
381
 
        rc += gt_write2byte (m->reserved, fp);
382
 
        return (rc);
383
 
}
384
 
 
385
 
/*
386
 
 * write media handler reference leaf atom
387
 
 */
388
 
int
389
 
write_hdlr_atom (gt_atom *a, FILE *fp)
390
 
{
391
 
        gt_hdlr_atom *m = (gt_hdlr_atom *)a;
392
 
        int rc = 0, len, i;
393
 
 
394
 
        if (m->size == 0)
395
 
                m->size = sizeof (gt_vmhd_atom);
396
 
        rc += gt_write4byte (m->size, fp);
397
 
        rc += gt_write4byte (m->type, fp);
398
 
        rc += fwrite (&m->version, 1, 1, fp);
399
 
        rc += fwrite (&m->flags, 1, 3, fp);
400
 
        rc += gt_write4byte (m->comp_type, fp);
401
 
        rc += gt_write4byte (m->comp_subtype, fp);
402
 
        rc += gt_write4byte (m->comp_man, fp);
403
 
        rc += gt_write4byte (m->comp_flags, fp);
404
 
        rc += gt_write4byte (m->comp_flags_mask, fp);
405
 
        if (!m->comp_name) {
406
 
                rc += fwrite ("\0", 1, 1, fp);
407
 
        } else {
408
 
                len = m->comp_name[0];
409
 
                if (len > 31) len = 31;
410
 
                for (i = 0; i < len+1; i++) {
411
 
                        rc += fwrite (m->comp_name+i, 1, 1, fp);
412
 
                }
413
 
        }
414
 
        return (rc);
415
 
}
416
 
 
417
 
/*
418
 
 * todo
419
 
 */
420
 
int
421
 
write_dref_atom (gt_atom *a, FILE *fp)
422
 
{
423
 
        gt_dref_atom *d = (gt_dref_atom *)a;
424
 
        int rc = 0, i;
425
 
 
426
 
        rc += gt_write4byte (d->size, fp);
427
 
        rc += gt_write4byte (d->type, fp);
428
 
        rc += fwrite (&d->version, 1, 1, fp);
429
 
        rc += fwrite (&d->flags, 1, 3, fp);
430
 
        rc += gt_write4byte (d->count, fp);
431
 
        for (i = 0; i < d->count; i++) {
432
 
                rc += gt_write4byte (d->tab[i].size, fp);
433
 
                rc += gt_write4byte (d->tab[i].type, fp);
434
 
                rc += fwrite (&d->tab[i].version, 1, 1, fp);
435
 
                rc += fwrite (&d->tab[i].flags, 1, 3, fp);
436
 
        }
437
 
        return (rc);
438
 
}
439
 
 
440
 
/*
441
 
 * write sample desc atom
442
 
 */
443
 
int
444
 
write_stsd_atom (gt_atom *a, FILE *fp)
445
 
{
446
 
        int i, rc = 0;
447
 
        gt_stsd_atom *s = (gt_stsd_atom *)a;
448
 
        gt_stsd_entry *te;
449
 
        gt_stsd_pano_entry *pte;
450
 
 
451
 
        rc += gt_write4byte (s->size, fp);
452
 
        rc += gt_write4byte (s->type, fp);
453
 
        rc += fwrite (&s->version, 1, 1, fp);
454
 
        rc += fwrite (&s->flags, 1, 3, fp);
455
 
        rc += gt_write4byte (s->count, fp);
456
 
        te = s->tab;
457
 
        for (i = 0; i < s->count; i++) {
458
 
                if (te->format == GT_VID_FMT_PANO) {
459
 
                        pte = (gt_stsd_pano_entry *)te;
460
 
                        rc += gt_write4byte(pte->size, fp);
461
 
                        rc += gt_write4byte(pte->format, fp);
462
 
                        rc += fwrite (&pte->reserved1, 1, 6, fp);
463
 
                        rc += gt_write2byte(pte->index, fp);
464
 
                        rc += gt_write4byte(pte->version, fp);
465
 
                        rc += gt_write4byte(pte->track_id, fp);
466
 
                        rc += gt_write4byte(pte->lowres_id, fp);
467
 
                        rc += fwrite (&pte->reserved2, 1, 24, fp);
468
 
                        rc += gt_write4byte(pte->hotspot_id, fp);
469
 
                        rc += fwrite (&pte->reserved3, 1, 36, fp);
470
 
                        rc += gt_write2byte(pte->hpan_start.high, fp);
471
 
                        rc += gt_write2byte(pte->hpan_start.low, fp);
472
 
                        rc += gt_write2byte(pte->hpan_end.high, fp);
473
 
                        rc += gt_write2byte(pte->hpan_end.low, fp);
474
 
                        rc += gt_write2byte(pte->vpan_top.high, fp);
475
 
                        rc += gt_write2byte(pte->vpan_top.low, fp);
476
 
                        rc += gt_write2byte(pte->vpan_bottom.high, fp);
477
 
                        rc += gt_write2byte(pte->vpan_bottom.low, fp);
478
 
                        rc += gt_write2byte(pte->min_zoom.high, fp);
479
 
                        rc += gt_write2byte(pte->min_zoom.low, fp);
480
 
                        rc += gt_write2byte(pte->max_zoom.high, fp);
481
 
                        rc += gt_write2byte(pte->max_zoom.low, fp);
482
 
                        rc += gt_write4byte(pte->size_x, fp);
483
 
                        rc += gt_write4byte(pte->size_y, fp);
484
 
                        rc += gt_write4byte(pte->no_frames, fp);
485
 
                        rc += gt_write2byte(pte->reserved4, fp);
486
 
                        rc += gt_write2byte(pte->no_frames_x, fp);
487
 
                        rc += gt_write2byte(pte->no_frames_y, fp);
488
 
                        rc += gt_write2byte(pte->color_depth, fp);
489
 
                        rc += gt_write4byte(pte->hs_size_x, fp);
490
 
                        rc += gt_write4byte(pte->hs_size_y, fp);
491
 
                        rc += gt_write2byte(pte->reserved5, fp);
492
 
                        rc += gt_write2byte(pte->hs_no_frames_x, fp);
493
 
                        rc += gt_write2byte(pte->hs_no_frames_y, fp);
494
 
                        rc += gt_write2byte(pte->hs_color_depth, fp);
495
 
                } else {
496
 
                        rc += gt_write4byte(te->size, fp);
497
 
                        rc += gt_write4byte(te->format, fp);
498
 
                        rc += fwrite (&te->reserved, 1, 6, fp);
499
 
                        rc += gt_write2byte(te->index, fp);
500
 
                        rc += gt_write2byte(te->version, fp);
501
 
                        rc += gt_write2byte(te->rev_level, fp);
502
 
                        rc += gt_write4byte(te->vendor, fp);
503
 
                        rc += gt_write4byte(te->temp_qual, fp);
504
 
                        rc += gt_write4byte(te->spat_qual, fp);
505
 
                        rc += gt_write2byte(te->width, fp);
506
 
                        rc += gt_write2byte(te->height, fp);
507
 
                        rc += gt_write2byte(te->hres.high, fp);
508
 
                        rc += gt_write2byte(te->hres.low, fp);
509
 
                        rc += gt_write2byte(te->vres.high, fp);
510
 
                        rc += gt_write2byte(te->vres.low, fp);
511
 
                        rc += gt_write4byte(te->data_size, fp);
512
 
                        rc += gt_write2byte(te->frame_count, fp);
513
 
                        rc += fwrite (&te->comp_name, 1, 32, fp);
514
 
                        rc += gt_write2byte(te->depth, fp);
515
 
                        rc += gt_write2byte(te->ctab_id, fp);
516
 
                }
517
 
                te = (gt_stsd_entry *)(((char *)te) + te->size);
518
 
        }
519
 
        return (rc);
520
 
}
521
 
 
522
 
/*
523
 
 * write time to sample atom
524
 
 */
525
 
int
526
 
write_stts_atom (gt_atom *a, FILE *fp)
527
 
{
528
 
        int i;
529
 
        gt_stts_atom *s = (gt_stts_atom *)a;
530
 
 
531
 
        gt_write4byte (s->size, fp);
532
 
        gt_write4byte (s->type, fp);
533
 
        fwrite (&s->version, 1, 1, fp);
534
 
        fwrite (&s->flags, 1, 3, fp);
535
 
        gt_write4byte (s->count, fp);
536
 
        for (i = 0; i < s->count; i++) {
537
 
                gt_write4byte(s->tab[i].num_samples, fp);
538
 
                gt_write4byte(s->tab[i].duration, fp);
539
 
        }
540
 
        return (0);
541
 
}
542
 
 
543
 
/*
544
 
 * write sample size atom
545
 
 */
546
 
int
547
 
write_stsz_atom (gt_atom *a, FILE *fp)
548
 
{
549
 
        gt_stsz_atom *s = (gt_stsz_atom *)a;
550
 
        int i, rc = 0;
551
 
 
552
 
        rc += gt_write4byte (s->size, fp);
553
 
        rc += gt_write4byte (s->type, fp);
554
 
        rc += fwrite (&s->version, 1, 1, fp);
555
 
        rc += fwrite (&s->flags, 1, 3, fp);
556
 
        rc += gt_write4byte (s->sample_size, fp);
557
 
        rc += gt_write4byte (s->count, fp);
558
 
        for (i = 0; i < s->count; i++) {
559
 
                rc += gt_write4byte(s->tab[i].size, fp);
560
 
        }
561
 
        return (rc);
562
 
}
563
 
 
564
 
/*
565
 
 * write sample to chunk leaf atom
566
 
 */
567
 
int
568
 
write_stsc_atom (gt_atom *a, FILE *fp)
569
 
{
570
 
        gt_stsc_atom *s = (gt_stsc_atom *)a;
571
 
        int i, rc = 0;
572
 
 
573
 
        rc += gt_write4byte (s->size, fp);
574
 
        rc += gt_write4byte (s->type, fp);
575
 
        rc += fwrite (&s->version, 1, 1, fp);
576
 
        rc += fwrite (&s->flags, 1, 3, fp);
577
 
        rc += gt_write4byte (s->count, fp);
578
 
        for (i = 0; i < s->count; i++) {
579
 
                rc += gt_write4byte(s->tab[i].first_chunk, fp);
580
 
                rc += gt_write4byte(s->tab[i].samples_per_chunk, fp);
581
 
                rc += gt_write4byte(s->tab[i].sample_id, fp);
582
 
        }
583
 
        return (rc);
584
 
}
585
 
/*
586
 
 * write sample chunk offset atom
587
 
 */
588
 
 
589
 
int
590
 
write_stco_atom (gt_atom *a, FILE *fp)
591
 
{
592
 
        int i;
593
 
        gt_stco_atom *s = (gt_stco_atom *)a;
594
 
 
595
 
        gt_write4byte (s->size, fp);
596
 
        gt_write4byte (s->type, fp);
597
 
        fwrite (&s->version, 1, 1, fp);
598
 
        fwrite (&s->flags, 1, 3, fp);
599
 
        gt_write4byte (s->count, fp);
600
 
        for (i = 0; i < s->count; i++) {
601
 
                gt_write4byte(s->tab[i].offset, fp);
602
 
        }
603
 
        return (0);
604
 
}
605
 
 
606
 
/*
607
 
 * write an atom and all it's subatoms
608
 
 */
609
 
int
610
 
gt_write_atom (gt_atom *a, FILE *fp)
611
 
{
612
 
        int i, rc = 0;
613
 
        char c = 0;
614
 
 
615
 
#ifdef DEBUG2
616
 
        fprintf (stderr,"gt_write_atom(%c%c%c%c) size=0x%x\n", (char)(a->type>>24),
617
 
                                (char)(a->type>>16),(char)(a->type>>8), (char)a->type,
618
 
                                a->size);
619
 
#endif
620
 
        if (GT_IS_CONTAINER (a)) {
621
 
                rc += gt_write4byte (a->size, fp);
622
 
                rc += gt_write4byte (a->type, fp);
623
 
                for (i = 0; i < a->memb; i++) {
624
 
                        rc += gt_write_atom (a->suba[i], fp);
625
 
                }
626
 
        } else
627
 
                switch (a->type) {
628
 
                /* leaf atoms
629
 
                 */
630
 
                case GTA_movie_header:
631
 
                        rc = write_mvhd_atom (a, fp); break;
632
 
                case GTA_user_data:
633
 
                        rc = write_udta_atom (a, fp); break;
634
 
                case GTA_track_header:
635
 
                        rc = write_tkhd_atom (a, fp); break;
636
 
                case GTA_media_header:
637
 
                        rc = write_mdhd_atom (a, fp); break;
638
 
                case GTA_handler_ref:
639
 
                        rc = write_hdlr_atom (a, fp); break;
640
 
                case GTA_data_ref:
641
 
                        rc = write_dref_atom (a, fp); break;
642
 
                case GTA_video_media_header:
643
 
                        rc = write_vmhd_atom (a, fp); break;
644
 
                case GTA_base_media_info:
645
 
                        rc = write_gmin_atom (a, fp); break;
646
 
                case GTA_sample_desc:
647
 
                        rc = write_stsd_atom (a, fp); break;
648
 
                case GTA_time_to_sample:
649
 
                        rc = write_stts_atom (a, fp); break;
650
 
                case GTA_sample_size:
651
 
                        rc = write_stsz_atom (a, fp); break;
652
 
                case GTA_sample_to_chunk:
653
 
                        rc = write_stsc_atom (a, fp); break;
654
 
                case GTA_chunk_offset:
655
 
                        rc = write_stco_atom (a, fp); break;
656
 
                case GTA_movie_data:
657
 
                case GTA_free:
658
 
                case GTA_skip:
659
 
                        rc = write_mdat_atom (a, fp); break;
660
 
                default:
661
 
                        fprintf(stderr, "gt_write_atom() Unknown atom type: %X size=%d\n",
662
 
                                                a->type,a->size);
663
 
                        /* write fill bytes */
664
 
                        gt_write4byte (a->size, fp);
665
 
                        gt_write4byte (a->type, fp);
666
 
                        for (i = 0; i < a->size - 8; i++) {
667
 
                                fwrite ((char *)&c, 1, 1, fp);
668
 
                        }
669
 
                        rc = -1;
670
 
                        break;
671
 
        }
672
 
        return (rc);
673
 
}
674
 
 
675
 
/*
676
 
 * misc tool functions */
677
 
 
678
 
/*
679
 
 * get qt/mac time value from current unix time
680
 
 */
681
 
unsigned int
682
 
gt_time (void)
683
 
{
684
 
        time_t t;
685
 
 
686
 
        time (&t);
687
 
        /* todo: this is just about the value it should be :) */
688
 
        return (t+(66*31536000)+1468800);
689
 
}
690
 
 
691
 
/*
692
 
 * todo
693
 
 */
694
 
gt_atom *
695
 
gt_get_track (FILE *fp)
696
 
{
697
 
        long start, pos;
698
 
        int rc;
699
 
        gt_atom *track, ac;
700
 
 
701
 
        start = pos = ftell (fp);
702
 
        track = gt_alloc_atom (GTA_track, MAX_SUBATOMS);
703
 
        track->memb = 0;
704
 
 
705
 
        rc = gt_read4byte (&track->size, fp);
706
 
        rc+= gt_read4byte (&track->type, fp);
707
 
        if ((rc < 8) || (track->type != GTA_track)) {
708
 
                gt_atom_free (track);
709
 
                return (NULL);
710
 
        }
711
 
        while (pos < start+track->size) {
712
 
                rc = gt_read4byte (&ac.size, fp);
713
 
                rc+= gt_read4byte (&ac.type, fp);
714
 
                if ((rc < 8) || (ac.type < 0x20202020)) {
715
 
                        gt_atom_free (track);
716
 
                        return (NULL);
717
 
                }
718
 
                track->suba[track->memb++] = gt_alloc_atom (ac.type, 0);
719
 
                track->suba[track->memb-1]->type = ac.type;
720
 
                track->suba[track->memb-1]->size = ac.size;
721
 
                fseek (fp, ac.size-8, SEEK_CUR);
722
 
                pos += 8 + ac.size;
723
 
        }
724
 
        return (track);
725
 
}
726
 
 
727
 
/*
728
 
 * todo ..
729
 
 */
730
 
gt_atom *
731
 
gt_get_movie (FILE *fp)
732
 
{
733
 
        int rc, start, pos;
734
 
        gt_atom ac, *ta, *moov = gt_alloc_atom (GTA_movie, MAX_SUBATOMS);
735
 
 
736
 
        start = ftell (fp);
737
 
        while (1) {
738
 
                rc = gt_read4byte (&moov->size, fp);
739
 
                rc+= gt_read4byte (&moov->type, fp);
740
 
                if ((rc < 8) || (moov->type < 0x20202020)) {
741
 
                        gt_atom_free (moov);
742
 
                        return (NULL);
743
 
                }
744
 
#ifdef DEBUG2
745
 
                printf (" get_movie() %c%c%c%c size=0x%X\n", ((char *)&moov->type)[3],
746
 
                                ((char*)&moov->type)[2], ((char*)&moov->type)[1],
747
 
                                ((char*)&moov->type)[0],moov->size);
748
 
#endif
749
 
                if (moov->type == GTA_movie) {
750
 
                        break;
751
 
                } else {
752
 
                        fseek (fp, moov->size - 8, SEEK_CUR);
753
 
                }
754
 
        }
755
 
 
756
 
        while (1) {
757
 
                pos = ftell (fp);
758
 
                if ((pos - start) >= moov->size) {
759
 
                        break;
760
 
                }
761
 
                rc = gt_read4byte (&ac.size, fp);
762
 
                rc+= gt_read4byte (&ac.type, fp);
763
 
                if (rc < 8) {
764
 
                        gt_atom_free (moov);
765
 
                        return (NULL);
766
 
                }
767
 
#ifdef DEBUG2
768
 
                printf (" -get_movie() %c%c%c%c size=0x%X\n", ((char *)&ac.type)[3],
769
 
                                ((char*)&ac.type)[2], ((char*)&ac.type)[1],
770
 
                                ((char*)&ac.type)[0],ac.size);
771
 
#endif
772
 
                switch (ac.type) {
773
 
                        /* leaf atoms */
774
 
                        case GTA_movie_header:
775
 
                        case GTA_track_header:
776
 
                        case GTA_edit_list:
777
 
                        case GTA_handler_ref:
778
 
                        case GTA_media_header:
779
 
                        case GTA_data_ref:
780
 
                        case GTA_video_media_header:
781
 
                        case GTA_sound_media_header:
782
 
                        case GTA_chunk_offset:
783
 
                        case GTA_sample_to_chunk:
784
 
                        case GTA_sample_desc:
785
 
                        case GTA_time_to_sample:
786
 
                        case GTA_sample_size:
787
 
                        case GTA_sync_sample:
788
 
                        case GTA_user_data:
789
 
                                fseek (fp, ac.size-8, SEEK_CUR);
790
 
                                break;
791
 
                        /* container atoms */
792
 
                        case GTA_track:
793
 
                        case GTA_edit:
794
 
                        case GTA_media:
795
 
                        case GTA_media_info:
796
 
                        case GTA_data_info:
797
 
                        case GTA_sample_table:
798
 
                                switch (ac.type) {
799
 
                                        case GTA_track:
800
 
                                                fseek (fp, -8, SEEK_CUR);
801
 
                                                moov->suba[moov->memb++] = gt_get_track (fp);
802
 
                                                break;
803
 
                                        default:
804
 
                                                ta = gt_alloc_atom (ac.type, MAX_SUBATOMS);
805
 
                                                ta->size = ac.size;
806
 
                                                ta->type = ac.type;
807
 
                                                moov->suba[moov->memb++] = ta;
808
 
                                                fseek (fp, ac.size-8, SEEK_CUR);
809
 
                                                break;
810
 
                                }
811
 
                                break;
812
 
                        default:
813
 
                                /* todo */
814
 
                                printf ("Unknow atom: %X\n", ac.type);
815
 
                                fseek (fp, ac.size-8, SEEK_CUR);
816
 
                                /* return (NULL); */
817
 
                                break;
818
 
                }
819
 
        }
820
 
        return (moov);
821
 
}
822
 
 
823
 
 
824
 
/*
825
 
 */
826
 
void
827
 
gt_swap4byte (ui32 *n)
828
 
{
829
 
        unsigned char t, *p = (unsigned char *)n;
830
 
 
831
 
        t = p[0];
832
 
        p[0] = p[3];
833
 
        p[3] = t;
834
 
        t = p[1];
835
 
        p[1] = p[2];
836
 
        p[2] = t;
837
 
}
838
 
 
839
 
/*
840
 
 */
841
 
void
842
 
gt_swap2byte (ui16 *n)
843
 
{
844
 
        unsigned char t, *p = (unsigned char *)n;
845
 
        t = p[0];
846
 
        p[0] = p[1];
847
 
        p[1] = t;
848
 
}
849
 
 
850
 
/* IO */
851
 
 
852
 
/*
853
 
 */
854
 
int
855
 
gt_write2byte (ui16 n, FILE *fp)
856
 
{
857
 
        int rc;
858
 
#ifdef LSB
859
 
        gt_swap2byte (&n);
860
 
#endif
861
 
        rc = fwrite (&n, 1, 2, fp);
862
 
        return (rc);
863
 
}
864
 
 
865
 
/*
866
 
 */
867
 
int
868
 
gt_write4byte (ui32 n, FILE *fp)
869
 
{
870
 
        int rc;
871
 
#ifdef LSB
872
 
        gt_swap4byte (&n);
873
 
#endif
874
 
        rc = fwrite (&n, 1, 4, fp);
875
 
        return (rc);
876
 
}
877
 
 
878
 
/*
879
 
 */
880
 
int
881
 
gt_read2byte (ui16 *n, FILE *fp)
882
 
{
883
 
        int rc;
884
 
 
885
 
        rc = fread (n, 1, 2, fp);
886
 
#ifdef LSB
887
 
        gt_swap2byte (n);
888
 
#endif
889
 
        return (rc);
890
 
}
891
 
 
892
 
/*
893
 
 */
894
 
int
895
 
gt_read4byte (ui32 *n, FILE *fp)
896
 
{
897
 
        int rc;
898
 
 
899
 
        rc = fread (n, 1, 4, fp);
900
 
#ifdef LSB
901
 
        gt_swap4byte (n);
902
 
#endif
903
 
#ifdef DEBUG2
904
 
        printf ("%s: gt_read4byte() pos=%ld val=%X ret=%d\n",
905
 
                        __FILE__, ftell(fp), *n, rc);
906
 
#endif
907
 
        return (rc);
908
 
}
909