4
* Copyright (C) 1998 Rasca, Berlin
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Library General Public
9
* License as published by the Free Software Foundation; either
10
* version 2 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Library General Public License for more details.
17
* You should have received a copy of the GNU Library General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
#define printid(s,x) printf("%s=%c%c%c%c\n",s,\
28
((char*)&x)[3],((char*)&x)[2],((char*)&x)[1],((char*)&x)[0])
33
* read 4 byte chars as id into the variable 'n'
36
gv_read_id(gv_u32 *n, FILE *fp)
39
rc = fread (n, 1, 4, fp);
47
* read 4 byte and swap if needed
50
gv_read4byte(gv_u32 *n, FILE *fp)
53
rc = fread (n, 1, 4, fp);
61
* read 2 byte and swap if needed
64
gv_read2byte(gv_u16 *n, FILE *fp)
67
rc = fread (n, 1, 2, fp);
77
gv_read_snd_strf (gv_avi_snd_strf *strf, FILE *fp)
80
in += gv_read_id (&strf->id, fp);
81
in += gv_read4byte (&strf->size, fp);
82
in += gv_read2byte (&strf->format, fp);
83
in += gv_read2byte (&strf->channels, fp);
84
in += gv_read4byte (&strf->rate, fp);
85
in += gv_read4byte (&strf->average_bps, fp);
86
in += gv_read2byte (&strf->blockalign, fp);
87
in += gv_read2byte (&strf->sample_size, fp);
88
printid (" strf id", strf->id);
90
printf (" snd format=%d channels=%d rate=%d sample_size=%d\n",
91
strf->format, strf->channels, strf->rate, strf->sample_size);
93
fseek (fp, strf->size - (in-8), SEEK_CUR);
94
return (strf->size+8);
100
gv_read_vid_strf (gv_avi_vid_strf *strf, FILE *fp)
103
in += gv_read_id (&strf->id, fp);
104
in += gv_read4byte (&strf->size, fp);
105
in += gv_read4byte (&strf->q_size, fp);
106
in += gv_read4byte (&strf->width, fp);
107
in += gv_read4byte (&strf->height, fp);
108
in += gv_read2byte (&strf->planes, fp);
109
in += gv_read2byte (&strf->bit_cnt, fp);
110
in += gv_read4byte (&strf->comp, fp);
111
in += gv_read4byte (&strf->image_size, fp);
112
in += gv_read4byte (&strf->xpels_meter, fp);
113
in += gv_read4byte (&strf->ypels_meter, fp);
114
in += gv_read4byte (&strf->num_colors, fp);
115
in += gv_read4byte (&strf->imp_colors, fp);
116
printid (" strf id", strf->id);
118
printf (" vid q_size=%d planes=%d bit_cnt=%d image_size=%d comp=%d\n",
119
strf->q_size, strf->planes, strf->bit_cnt, strf->image_size,strf->comp);
120
printf (" --- xpels=%d ypels=%d\n", strf->xpels_meter, strf->ypels_meter);
122
fseek (fp, strf->size - (in-8), SEEK_CUR);
123
return (strf->size+8);
129
gv_read_strh (gv_avi_strh *strh, FILE *fp)
132
in += gv_read_id (&strh->id, fp);
133
in += gv_read4byte (&strh->size, fp);
134
in += gv_read_id (&strh->type, fp);
135
in += gv_read4byte (&strh->fcc_handler, fp);
136
in += gv_read4byte (&strh->priority, fp);
137
in += gv_read4byte (&strh->init_fr, fp);
138
in += gv_read4byte (&strh->scale, fp);
139
in += gv_read4byte (&strh->rate, fp);
140
in += gv_read4byte (&strh->start, fp);
141
in += gv_read4byte (&strh->length, fp);
142
in += gv_read4byte (&strh->buf_size, fp);
143
in += gv_read4byte (&strh->quality, fp);
144
in += gv_read4byte (&strh->sample_size, fp);
145
printid (" strh id", strh->id);
146
printid (" strh type", strh->type);
148
printf (" scale=%d buf_size=%d smpl size=%d\n",
149
strh->scale, strh->buf_size, strh->sample_size);
151
fseek (fp, strh->size - (in-8), SEEK_CUR);
152
return (strh->size+8);
158
gv_read_avi_header (gv_avi_hdrl *hdrl, FILE *fp, int size)
162
gv_avi_vid_strf *vid_strf;
163
gv_avi_snd_strf *snd_strf;
164
gv_u32 list_id, list_size, list_type;
166
in += gv_read_id (&hdrl->avih.id, fp);
167
in += gv_read4byte (&hdrl->avih.size, fp);
168
printid ("avih",hdrl->avih.id);
170
printf ("%d: size=%d (%d)\n",__LINE__,hdrl->avih.size, sizeof(hdrl->avih));
172
in += gv_read4byte (&hdrl->avih.us_pf, fp);
173
in += gv_read4byte (&hdrl->avih.bps, fp);
174
in += gv_read4byte (&hdrl->avih.pad_gran, fp);
175
in += gv_read4byte (&hdrl->avih.flags, fp);
176
in += gv_read4byte (&hdrl->avih.frames, fp);
177
in += gv_read4byte (&hdrl->avih.init_fr, fp);
178
in += gv_read4byte (&hdrl->avih.streams, fp);
179
in += gv_read4byte (&hdrl->avih.buf_size, fp);
180
in += gv_read4byte (&hdrl->avih.width, fp);
181
in += gv_read4byte (&hdrl->avih.height, fp);
182
in += gv_read4byte (&hdrl->avih.scale, fp);
183
in += gv_read4byte (&hdrl->avih.rate, fp);
184
in += gv_read4byte (&hdrl->avih.start, fp);
185
in += gv_read4byte (&hdrl->avih.length, fp);
187
if (hdrl->avih.streams > 0) {
188
streams = hdrl->avih.streams;
189
hdrl->str = malloc (sizeof (gv_stream_hdr) * streams);
193
for (i = 0; i < streams; i++) {
194
in += gv_read_id (&list_id, fp);
195
in += gv_read4byte (&list_size, fp);
196
in += gv_read_id (&list_type, fp);
197
if (list_type != GV_STRL) {
198
fseek (fp, list_size-4, SEEK_CUR);
200
printf ("%s: skipping ..\n", __FILE__);
204
in += gv_read_strh (&hdrl->str[i].strh, fp);
205
switch (hdrl->str[i].strh.type) {
207
vid_strf = malloc (sizeof (gv_avi_vid_strf));
208
hdrl->str[i].strf = vid_strf;
209
in += gv_read_vid_strf (vid_strf, fp);
212
snd_strf = malloc (sizeof (gv_avi_snd_strf));
213
hdrl->str[i].strf = snd_strf;
214
in += gv_read_snd_strf (snd_strf, fp);
217
printf ("oops: file %s, line %d\n", __FILE__, __LINE__);
221
fseek (fp, size-(in+4), SEEK_CUR);
223
printf ("%d: size=%d in=%d pos=%ld\n", __LINE__, size, in, ftell(fp));
229
* read the avi header
232
gv_read_header (FILE *fp, FILE *fp_snd)
235
gv_u32 list_id, list_size, list_type;
237
avi = malloc (sizeof (gv_avi));
242
avi->fp_snd = fp_snd;
245
gv_read_id (&avi->id, fp);
246
if (avi->id != GV_RIFF)
248
gv_read4byte (&avi->size, fp);
249
gv_read_id (&avi->type, fp);
250
if (avi->type != GV_AVI)
254
gv_read_id (&list_id, fp);
255
gv_read4byte (&list_size, fp);
256
gv_read_id (&list_type, fp);
257
printid ("list id", list_id);
258
printid ("list type", list_type);
260
if (list_id != GV_LIST)
264
gv_read_avi_header (&avi->hdrl, fp, list_size);
268
avi->d_pos = ftell (fp);
269
fseek (fp_snd, avi->d_pos, SEEK_SET);
270
printf (" d_pos=%ld\n", avi->d_pos);
275
fseek (fp, list_size, SEEK_SET);
286
* convert from rgb555 to rgb565
289
gv_get_frame_15to16 (gv_avi *avi, gv_byte *buf, int pad)
291
gv_u32 atom_id, atom_size;
292
register int in = 0, y, x;
293
register int width = avi->hdrl.avih.width;
294
register int height = avi->hdrl.avih.height;
296
gv_stream_hdr *str = gv_video_stream (avi, 0);
297
int bytes_per_pixel = ((gv_avi_vid_strf *)str->strf)->bit_cnt;
298
int out_line_size = width * 2;
299
int line_size = width * 2;
300
int image_size = width * height * bytes_per_pixel /8;
305
in = gv_read_id (&atom_id, avi->fp);
306
in += gv_read4byte (&atom_size, avi->fp);
307
if (in != 8) {/* eof? */
312
line = malloc (line_size);
313
for (y = 0; y < height; y++) {
314
ptr = buf+(height - y - 1)*(out_line_size + pad);
315
if (fread (line, 1, line_size, avi->fp) < line_size) {
319
rgb = (gv_u16 *)line;
321
for (x = 0; x < width; x++) {
322
*u16++ = ((*rgb & 0xFFE0)<<1) | (*rgb & 0x001F);
327
if (atom_size - image_size > 0)
328
fseek (avi->fp, atom_size - image_size, SEEK_CUR);
332
/* skip sound sample */
333
fseek (avi->fp, atom_size, SEEK_CUR);
337
printf ("oops: id=%d\n", atom_id);
344
* convert from rgb555 to rgb888
347
gv_get_frame_15to24 (gv_avi *avi, gv_byte *buf, int pad)
349
gv_u32 atom_id, atom_size;
350
register int in = 0, y, x;
351
register int width = avi->hdrl.avih.width;
352
register int height = avi->hdrl.avih.height;
353
int out_line_size = width * 3;
354
int line_size = width * 2;
355
int image_size = line_size * height;
360
in = gv_read_id (&atom_id, avi->fp);
361
in += gv_read4byte (&atom_size, avi->fp);
362
if (in != 8) /* eof? */
367
line = malloc (line_size);
368
for (y = 0; y < height; y++) {
369
ptr = buf+(height - y - 1)*(out_line_size + pad);
370
if (fread (line, 1, line_size, avi->fp) < line_size) {
374
rgb = (gv_u16 *)line;
375
for (x = 0; x < width; x++) {
376
*ptr++ = ((*rgb) & 0x001F) << 3;
377
*ptr++ = ((*rgb) & 0x03E0) >> 2;
378
*ptr++ = ((*rgb) & 0x7C00) >> 7;
383
if (atom_size - image_size > 0)
384
fseek (avi->fp, atom_size - image_size, SEEK_CUR);
388
/* skip sound sample */
389
fseek (avi->fp, atom_size, SEEK_CUR);
393
printf ("oops: id=%d\n", atom_id);
400
* convert to rgb555 or rgb565
403
gv_get_frame_24toX (gv_avi *avi, gv_byte *buf, int pad, int bits)
405
gv_u32 atom_id, atom_size;
406
register int in = 0, y, x;
407
register int width = avi->hdrl.avih.width;
408
register int height = avi->hdrl.avih.height;
410
gv_stream_hdr *str = gv_video_stream (avi, 0);
411
int bytes_per_pixel = ((gv_avi_vid_strf *)str->strf)->bit_cnt;
412
int out_line_size = width * 2;
413
int line_size = width * 3;
414
int image_size = width * height * bytes_per_pixel /8;
415
register int gshift = 0, bshift = 0;
420
in = gv_read_id (&atom_id, avi->fp);
421
in += gv_read4byte (&atom_size, avi->fp);
422
if (in != 8) /* eof? */
427
line = malloc (line_size);
435
for (y = 0; y < height; y++) {
436
ptr = buf+(height - y - 1)*(out_line_size + pad);
437
if (fread (line, 1, line_size, avi->fp) < line_size) {
443
for (x = 0; x < width; x++) {
444
*u16++ = (rgb[2] >> 3) | ((rgb[1]>>gshift)<<5) |
445
((rgb[0]>>3)<<bshift);
450
if (atom_size - image_size > 0)
451
fseek (avi->fp, atom_size - image_size, SEEK_CUR);
455
/* skip sound sample */
456
fseek (avi->fp, atom_size, SEEK_CUR);
460
printf ("oops: id=%d\n", atom_id);
467
* returns image in native format
470
gv_get_frame_raw (gv_avi *avi, gv_byte *buf, int pad)
472
gv_u32 atom_id, atom_size;
473
register int in = 0, y, i;
474
register int width = avi->hdrl.avih.width;
475
register int height = avi->hdrl.avih.height;
476
gv_stream_hdr *str = gv_video_stream (avi, 0);
477
int bytes_per_pixel = ((gv_avi_vid_strf *)str->strf)->bit_cnt / 8;
478
int line_size = width * bytes_per_pixel;
479
int image_size = width * height * bytes_per_pixel;
483
in = gv_read_id (&atom_id, avi->fp);
484
in += gv_read4byte (&atom_size, avi->fp);
485
if (in != 8) /* eof? */
491
printf ("%s: size=%d\n", __FILE__, atom_size);
493
for (y = 0; y < height; y++) {
494
ptr = buf+(height - y - 1)*(line_size + pad);
495
if (fread (ptr, 1, line_size, avi->fp) < line_size)
497
if (bytes_per_pixel == 3) {
498
for (i = 0; i < line_size; i+=3) {
505
if (atom_size - image_size > 0)
506
fseek (avi->fp, atom_size - image_size, SEEK_CUR);
510
/* skip sound sample */
511
fseek (avi->fp, atom_size, SEEK_CUR);
515
printf ("oops: id=%d\n", atom_id);
524
gv_video_stream (gv_avi *avi, int num) {
527
for (i = 0; i < avi->hdrl.avih.streams; i++) {
528
if (avi->hdrl.str[i].strh.type == GV_VIDS) {
530
return (&avi->hdrl.str[i]);
540
gv_sound_stream (gv_avi *avi, int num) {
543
for (i = 0; i < avi->hdrl.avih.streams; i++) {
544
if (avi->hdrl.str[i].strh.type == GV_AUDS) {
546
return (&avi->hdrl.str[i]);
556
gv_reset (gv_avi *avi)
559
printf ("%s: gv_reset() d_pos=%ld\n", __FILE__, avi->d_pos);
562
fseek (avi->fp, avi->d_pos, SEEK_SET);
563
fseek (avi->fp_snd, avi->d_pos, SEEK_SET);
570
gv_skip_frame (gv_avi *avi)
573
gv_u32 atom_id, atom_size;
576
printf ("%s: gv_skip_frame()\n", __FILE__);
579
in = gv_read_id (&atom_id, avi->fp);
580
in += gv_read4byte (&atom_size, avi->fp);
581
if (in != 8) /* eof? */
586
fseek (avi->fp, atom_size, SEEK_CUR);
590
fseek (avi->fp, atom_size, SEEK_CUR);