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

« back to all changes in this revision

Viewing changes to gt/ppm2qt.c

  • Committer: Bazaar Package Importer
  • Author(s): Christian Marillat
  • Date: 2004-08-29 10:53:42 UTC
  • Revision ID: james.westby@ubuntu.com-20040829105342-qgmnry37eadfkoxx
Tags: upstream-1.1.3
ImportĀ upstreamĀ versionĀ 1.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ppm2qt.c
 
3
 * just a dirty hack!
 
4
 *
 
5
 * Copyright (C) 1998 Rasca, Berlin
 
6
 * EMail: thron@gmx.de
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 2 of the License, or
 
11
 * (at your option) any later version.
 
12
 *
 
13
 * This program 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
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program; 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 <getopt.h>
 
26
#include "gt.h"
 
27
 
 
28
/*
 
29
 */
 
30
static void
 
31
usage (char *progname)
 
32
{
 
33
        printf (
 
34
                "Usage: %s "
 
35
                "[-v] "
 
36
                "[-t #] "
 
37
                "[-j] "
 
38
                "[-s #x#] "
 
39
                "-o <output> <input-files ..>\n", progname);
 
40
        exit (1);
 
41
}
 
42
 
 
43
/*
 
44
 * read ppm header of a rawbits ppm file (P6)
 
45
 */
 
46
int
 
47
read_ppm_header (FILE *fp, int *width, int *height)
 
48
{
 
49
        char buff[128];
 
50
 
 
51
        *width = *height = 0;
 
52
        while (*width == 0) {
 
53
                fgets (buff, 128, fp);
 
54
                if (*buff == 'P') {
 
55
                        if (*(buff+1) != '6')
 
56
                                printf ("Warning.. not a binary ppm file?\n");
 
57
                } else if ((*buff != '#') && (*buff != '\n')) {
 
58
                        if (!*width) {
 
59
                                sscanf (buff, "%d %d", width, height);
 
60
                                fgets (buff, 128, fp);
 
61
                                break;
 
62
                        }
 
63
                }
 
64
        }
 
65
        if (*width && *height)
 
66
                return (1);
 
67
        return (0);
 
68
}
 
69
 
 
70
/*
 
71
 * todo: renaming of structures
 
72
 */
 
73
gt_atom *
 
74
write_moov_atom (FILE *fp, int width, int height, int num_frames, int tpf,
 
75
                int format)
 
76
{
 
77
        int i;
 
78
        gt_stsd_atom *stsd;
 
79
        gt_stts_atom *stts;
 
80
        gt_stsc_atom *stsc;
 
81
        gt_stsz_atom *stsz;
 
82
        gt_stco_atom *stco;
 
83
        gt_stbl_atom *stbl;
 
84
        gt_vmhd_atom *vmhd;
 
85
        gt_hdlr_atom *minf_hdlr;
 
86
        gt_hdlr_atom *mdia_hdlr;
 
87
        gt_dref_atom *dref;
 
88
        gt_dinf_atom *dinf;
 
89
        gt_mdhd_atom *mdhd;
 
90
        gt_tkhd_atom *tkhd;
 
91
        gt_trak_atom *trak;
 
92
        gt_mdia_atom *mdia;
 
93
        gt_mvhd_atom *mvhd;
 
94
        gt_udta_atom *udta;
 
95
        gt_atom *minf, *moov;
 
96
 
 
97
        /* sample description atom */
 
98
        stsd = gt_alloc_atom (GTA_sample_desc, 1);
 
99
        stsd->count = 1;
 
100
        stsd->tab->size = 86;
 
101
    stsd->tab->format = format;
 
102
    stsd->tab->index = 1;   /* points to an entry in 'dref' */
 
103
    stsd->tab->width = width;
 
104
    stsd->tab->height = height;
 
105
    stsd->tab->hres.high = 72;
 
106
    stsd->tab->vres.high = 72;
 
107
    stsd->tab->frame_count = 1;
 
108
        strcpy (stsd->tab->comp_name+1, GT_COMP_RAW);
 
109
        stsd->tab->comp_name[0] = strlen (GT_COMP_RAW);
 
110
        stsd->tab->depth =24;
 
111
        stsd->tab->ctab_id = -1;
 
112
        /* time to sample atom */
 
113
    stts = gt_alloc_atom (GTA_time_to_sample, 1);
 
114
    stts->count = 1;
 
115
    stts->tab->num_samples = num_frames;
 
116
    stts->tab->duration = tpf;
 
117
        /* sample to chunk  */
 
118
    stsc = gt_alloc_atom (GTA_sample_to_chunk, 1);
 
119
    stsc->count = 1;
 
120
    stsc->tab->first_chunk = 1;
 
121
    stsc->tab->samples_per_chunk = stts->tab->num_samples;
 
122
    stsc->tab->sample_id = 1;   /* point to the first entry in the stsd tab!? */
 
123
        /* sample size atom .. */
 
124
        stsz = gt_alloc_atom (GTA_sample_size, num_frames);
 
125
        stsz->sample_size = 0;
 
126
        stsz->count = num_frames;
 
127
        for (i = 0; i < num_frames; i++ ) {
 
128
                stsz->tab[i].size = width * height * 3;
 
129
        }
 
130
        /* sample chunk offset atom */
 
131
        stco = gt_alloc_atom (GTA_chunk_offset, 1);
 
132
        stco->count = 1;
 
133
        stco->tab[0].offset = 0;    /*  offset of mdat */
 
134
    /* sample table */
 
135
    stbl = gt_alloc_atom (GTA_sample_table, 5);
 
136
    stbl->memb = 5;
 
137
    stbl->suba[0] = (gt_atom*)stsd;
 
138
    stbl->suba[1] = (gt_atom*)stts;
 
139
    stbl->suba[2] = (gt_atom*)stsc;
 
140
    stbl->suba[3] = (gt_atom*)stsz;
 
141
    stbl->suba[4] = (gt_atom*)stco;
 
142
    stbl->size = 8 +
 
143
            stsd->size + stts->size + stsc->size + stsz->size + stco->size;
 
144
    /* video media information header */
 
145
    vmhd = gt_alloc_atom (GTA_video_media_header, 0);
 
146
    vmhd->flags[2] = 1;
 
147
        /* data handler reference atom ??? */
 
148
        minf_hdlr = gt_alloc_atom (GTA_handler_ref, 0);
 
149
        minf_hdlr->comp_type = GT_DATA_REF;
 
150
        minf_hdlr->comp_subtype = GT_ALIAS;
 
151
        minf_hdlr->comp_man = GT_COMP_MAN;
 
152
        /* */
 
153
    dref = gt_alloc_atom (GTA_data_ref, 1);
 
154
    dref->count = 1;
 
155
    dref->tab->size = 12;
 
156
    dref->tab->type = GT_ALIAS;
 
157
    dref->tab->flags[2]= 0x01;  /* self reference */
 
158
        /* */
 
159
    dinf = gt_alloc_atom (GTA_data_info, 1);
 
160
    dinf->memb = 1;
 
161
    dinf->suba[0] = (gt_atom *)dref;
 
162
    dinf->size = 8 + dref->size;
 
163
 
 
164
    /* media information atom */
 
165
    minf = gt_alloc_atom (GTA_media_info, 4);
 
166
    minf->memb = 4;
 
167
    minf->suba[0] = (gt_atom *)vmhd;
 
168
    minf->suba[1] = (gt_atom *)minf_hdlr;
 
169
    minf->suba[2] = (gt_atom *)dinf;
 
170
    minf->suba[3] = (gt_atom *)stbl;
 
171
    minf->size += vmhd->size + minf_hdlr->size + dinf->size + stbl->size;
 
172
        /* media header */
 
173
    mdhd = gt_alloc_atom (GTA_media_header, 0);
 
174
    mdhd->ctime = gt_time();
 
175
    mdhd->mtime = gt_time();
 
176
    mdhd->time_scale = 1000;
 
177
    mdhd->duration = tpf * num_frames;
 
178
        /* media handler reference atom */
 
179
    mdia_hdlr = gt_alloc_atom (GTA_handler_ref, strlen(GT_MID_HDLR_NAME));
 
180
    mdia_hdlr->comp_type = GT_MEDIA_REF;
 
181
    mdia_hdlr->comp_subtype = GT_VIDEO;
 
182
    mdia_hdlr->comp_man = GT_COMP_MAN;
 
183
    mdia_hdlr->comp_flags = 0x40000000;     /* ? */
 
184
    mdia_hdlr->comp_flags_mask = 0x00010047;    /* ? */
 
185
    strcpy (mdia_hdlr->comp_name+1, GT_MID_HDLR_NAME);
 
186
    mdia_hdlr->comp_name[0] = strlen (GT_MID_HDLR_NAME);
 
187
    mdia_hdlr->size = 32 + 1 +strlen (GT_MID_HDLR_NAME);
 
188
        /* media atom */
 
189
        mdia = gt_alloc_atom (GTA_media, 3);
 
190
        mdia->memb = 3;
 
191
        mdia->suba[0] = (gt_atom *)mdhd;
 
192
    mdia->suba[1] = (gt_atom *)mdia_hdlr;
 
193
    mdia->suba[2] = (gt_atom *)minf;
 
194
    mdia->size += mdhd->size + mdia_hdlr->size + minf->size;
 
195
        /* track header */
 
196
    tkhd = gt_alloc_atom (GTA_track_header,0);
 
197
    tkhd->flags[2] = (char)(0x01 | 0x02);
 
198
    tkhd->ctime = gt_time();
 
199
    tkhd->mtime = gt_time();
 
200
    tkhd->track_id = 1;
 
201
    tkhd->duration = tpf * num_frames;
 
202
    tkhd->matrix[1]  = 1;   /* 1/1/1 */
 
203
    tkhd->matrix[17] = 1;
 
204
    tkhd->matrix[32] = 64;
 
205
    tkhd->width.high = width;
 
206
    tkhd->height.high= height;
 
207
        /* track */
 
208
    trak = gt_alloc_atom (GTA_track, 2);
 
209
    trak->memb = 2;
 
210
    trak->suba[0] = (gt_atom *)tkhd;
 
211
    trak->suba[1] = (gt_atom *)mdia;
 
212
    trak->size += tkhd->size + mdia->size;
 
213
        /* movie header */
 
214
    mvhd = gt_alloc_atom (GTA_movie_header, 0);
 
215
    mvhd->ctime = gt_time();
 
216
    mvhd->mtime = gt_time();
 
217
    mvhd->time_scale = 1000;
 
218
    mvhd->duration = tkhd->duration;
 
219
    mvhd->pref_rate.high = 1;
 
220
    mvhd->matrix[1] =  1;   /* 1/1/1 */
 
221
    mvhd->matrix[17] = 1;
 
222
    mvhd->matrix[32] = 64;
 
223
    mvhd->next_track_id = 2;
 
224
    /* user data
 
225
        no space for the text pointers is provided! */
 
226
    udta = gt_alloc_atom (GTA_user_data, 3);
 
227
    udta->tab[0]->type = GT_UD_INFO;
 
228
    udta->tab[0]->tlen = strlen ("Made by 'ppm2qt'");
 
229
    udta->tab[0]->size = 8 + 4 + udta->tab[0]->tlen;
 
230
    udta->tab[0]->text = "Made by 'ppm2qt'";
 
231
    udta->tab[1]->type = GT_UD_PRODUCER;
 
232
    udta->tab[1]->tlen = strlen ("ppm2qt User");
 
233
    udta->tab[1]->size = 8 + 4 + udta->tab[1]->tlen;
 
234
    udta->tab[1]->text = "ppm2qt User";
 
235
    udta->tab[2]->type = GT_UD_LOOP;
 
236
    udta->tab[2]->size = 8;
 
237
    udta->size = 8 +udta->tab[0]->size +udta->tab[1]->size +udta->tab[2]->size;
 
238
    /* movie atom, with 3 subatoms */
 
239
    moov = gt_alloc_atom (GTA_movie, 3);
 
240
    moov->memb = 3;
 
241
    moov->suba[0] = (gt_atom *)mvhd;
 
242
    moov->suba[1] = (gt_atom *)udta;
 
243
    moov->suba[2] = (gt_atom *)trak;
 
244
    moov->size += mvhd->size + udta->size + trak->size;
 
245
        stco->tab[0].offset = moov->size + 8 ;    /*  offset of mdat */
 
246
        if (!gt_write_atom (moov, fp)) {
 
247
                perror ("write_moov_atom()");
 
248
                exit (1);
 
249
        }
 
250
        return (moov);
 
251
}
 
252
 
 
253
/*
 
254
 * ppm2qt, all frames must have the same size and must
 
255
 * be an raw ppm file..
 
256
 */
 
257
int
 
258
main (int argc, char *argv[]) {
 
259
        int c, num_frames, verbose = 0;
 
260
        int width = 0, height = 0;
 
261
        int y, i, ti, time_per_frame=40;
 
262
        char *outfile = NULL, *infile = NULL;
 
263
        byte *line;
 
264
        FILE *fp, *outfp;
 
265
        int input_is_jpeg = 0;
 
266
        int format = GT_VID_FMT_RAW;
 
267
        byte *buf = NULL;
 
268
        gt_atom *moov;
 
269
 
 
270
        while ((c = getopt (argc, argv, "?ho:vt:js:")) != EOF) {
 
271
                switch (c) {
 
272
                        case 'o':
 
273
                                outfile = optarg;
 
274
                                break;
 
275
                        case 'v':
 
276
                                verbose = 1;
 
277
                                break;
 
278
                        case 't':
 
279
                                /* default = 40 tpf =~ 25 fps */
 
280
                                time_per_frame = atoi(optarg);
 
281
                                break;
 
282
                        case 'j':
 
283
                                input_is_jpeg = 1;
 
284
                                format = GT_VID_FMT_JPEG;
 
285
                                break;
 
286
                        case 's':
 
287
                                sscanf (optarg, "%dx%d", &width, &height);
 
288
                                break;
 
289
                        case '?':
 
290
                        case 'h':
 
291
                        default:
 
292
                                usage (argv[0]);
 
293
                                break;
 
294
                }
 
295
        }
 
296
        num_frames = argc - optind;
 
297
        if (!outfile || !num_frames)
 
298
                usage (argv[0]);
 
299
 
 
300
        if (input_is_jpeg && (!width || !height)) {
 
301
                fprintf (stderr, "You must specify the size!\n");
 
302
                usage (argv[0]);
 
303
        } else if (!input_is_jpeg) {
 
304
                /* read the first file to get the size
 
305
                 */
 
306
                if (width || height) {
 
307
                        fprintf (stderr, "Size option only allowed for ppm files\n");
 
308
                        usage (argv[0]);
 
309
                }
 
310
                infile = argv[optind];
 
311
                if (verbose)
 
312
                        printf ("reading size from '%s'\n", infile);
 
313
                if ((fp = fopen (infile, "rb")) == NULL) {
 
314
                        perror (infile);
 
315
                        usage (argv[0]);
 
316
                        exit (2);
 
317
                }
 
318
                if (!read_ppm_header (fp, &width, &height)) {
 
319
                        printf ("%s: not a ppm file?\n", infile);
 
320
                }
 
321
                fclose (fp);
 
322
        } else {
 
323
                buf = malloc (width * height * 3);
 
324
        }
 
325
        if (!width || !height) {
 
326
                printf ("failed! no width or height found\n");
 
327
                exit (3);
 
328
        }
 
329
        /* open output file
 
330
         */
 
331
        if ((outfp = fopen (outfile, "wb")) == NULL) {
 
332
                perror (infile);
 
333
                exit (4);
 
334
        }
 
335
        /* write moov atom
 
336
         */
 
337
        moov = write_moov_atom (outfp,
 
338
                                width, height, num_frames, time_per_frame, format);
 
339
        /* write mdat size/atom type
 
340
         */
 
341
        gt_write4byte (8 + num_frames * width * height * 3, outfp);
 
342
        gt_write4byte (GTA_movie_data, outfp);
 
343
 
 
344
        line = malloc (width * 3);
 
345
        /* loop for every frame
 
346
         */
 
347
        for (i = 0; i < num_frames; i++) {
 
348
                infile = argv[optind+i];
 
349
                if (verbose)
 
350
                        printf ("infile = '%s'\n", infile);
 
351
                if ((fp = fopen (infile, "rb")) == NULL) {
 
352
                        perror (infile);
 
353
                        exit (6);
 
354
                }
 
355
                if (input_is_jpeg) {
 
356
                        int len;
 
357
                        len = fread (buf, 1, width * height * 3, fp);
 
358
                        fwrite (buf, 1, len, outfp);
 
359
                        ((gt_stsz_atom *)(
 
360
                                moov ->
 
361
                                suba[2] ->
 
362
                                suba[1] -> /* mdia */
 
363
                                suba[2] -> /* minf */
 
364
                                suba[3] -> /* stbl */
 
365
                                suba[3]))-> /* stsz */
 
366
                                                tab[i].size = len;
 
367
                } else {
 
368
                        if (!read_ppm_header (fp, &ti, &ti)) {
 
369
                                printf ("%s: no ppm file?\n", infile);
 
370
                        } else {
 
371
                                for (y = 0; y < height; y++) {
 
372
                                        fread (line, 1, width*3, fp);
 
373
                                        fwrite (line, 1, width * 3, outfp);
 
374
                                }
 
375
                        }
 
376
                }
 
377
                fclose (fp);
 
378
        }
 
379
        if (input_is_jpeg) {
 
380
                fseek (outfp, 0, SEEK_SET);
 
381
                gt_write_atom (moov, outfp);
 
382
        }
 
383
        fclose (outfp);
 
384
        return (0);
 
385
}
 
386