c syntax update patch by (mru at users dot sourceforge dot net (Måns Rullgård))
[ffmpeg.git] / libav / img.c
1 /*
2  * Image format
3  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 #include "avformat.h"
20
21 extern AVInputFormat pgm_iformat;
22 extern AVOutputFormat pgm_oformat;
23 extern AVInputFormat pgmyuv_iformat;
24 extern AVOutputFormat pgmyuv_oformat;
25 extern AVInputFormat ppm_iformat;
26 extern AVOutputFormat ppm_oformat;
27 extern AVInputFormat imgyuv_iformat;
28 extern AVOutputFormat imgyuv_oformat;
29 extern AVInputFormat pgmpipe_iformat;
30 extern AVOutputFormat pgmpipe_oformat;
31 extern AVInputFormat pgmyuvpipe_iformat;
32 extern AVOutputFormat pgmyuvpipe_oformat;
33 extern AVInputFormat ppmpipe_iformat;
34 extern AVOutputFormat ppmpipe_oformat;
35 extern AVOutputFormat yuv4mpegpipe_oformat;
36
37 #define IMGFMT_YUV     1
38 #define IMGFMT_PGMYUV  2
39 #define IMGFMT_PGM     3
40 #define IMGFMT_PPM     4
41 #define IMGFMT_YUV4MPEG     5
42
43 #define Y4M_MAGIC "YUV4MPEG2"
44 #define Y4M_FRAME_MAGIC "FRAME"
45 #define Y4M_LINE_MAX 256
46
47 typedef struct {
48     int width;
49     int height;
50     int img_number;
51     int img_size;
52     int img_fmt;
53     int is_pipe;
54     int header_written;
55     char path[1024];
56 } VideoData;
57
58 static inline int pnm_space(int c)  
59 {
60     return (c==' ' || c=='\n' || c=='\r' || c=='\t');
61 }
62
63 static void pnm_get(ByteIOContext *f, char *str, int buf_size) 
64 {
65     char *s;
66     int c;
67     
68     do  {
69         c=get_byte(f);
70         if (c=='#')  {
71             do  {
72                 c=get_byte(f);
73             } while (c!='\n');
74             c=get_byte(f);
75         }
76     } while (pnm_space(c));
77     
78     s=str;
79     do  {
80         if (url_feof(f))
81             break;
82         if ((s - str)  < buf_size - 1)
83             *s++=c;
84         c=get_byte(f);
85     } while (!pnm_space(c));
86     *s = '\0';
87 }
88
89 static int pgm_read(VideoData *s, ByteIOContext *f, UINT8 *buf, int size, int is_yuv)
90 {
91     int width, height, i;
92     char buf1[32];
93     UINT8 *picture[3];
94
95     width = s->width;
96     height = s->height;
97
98     pnm_get(f, buf1, sizeof(buf1));
99     if (strcmp(buf1, "P5")) {
100         return -EIO;
101     }
102     pnm_get(f, buf1, sizeof(buf1));
103     pnm_get(f, buf1, sizeof(buf1));
104     pnm_get(f, buf1, sizeof(buf1));
105     
106     picture[0] = buf;
107     picture[1] = buf + width * height;
108     picture[2] = buf + width * height + (width * height / 4);
109     get_buffer(f, picture[0], width * height);
110     
111     height>>=1;
112     width>>=1;
113     if (is_yuv) {
114         for(i=0;i<height;i++) {
115             get_buffer(f, picture[1] + i * width, width);
116             get_buffer(f, picture[2] + i * width, width);
117         }
118     } else {
119         for(i=0;i<height;i++) {
120             memset(picture[1] + i * width, 128, width);
121             memset(picture[2] + i * width, 128, width);
122         }
123     }
124     return 0;
125 }
126
127 static int ppm_read(VideoData *s, ByteIOContext *f, UINT8 *buf, int size)
128 {
129     int width, height;
130     char buf1[32];
131     UINT8 *picture[3];
132
133     width = s->width;
134     height = s->height;
135
136     pnm_get(f, buf1, sizeof(buf1));
137     if (strcmp(buf1, "P6")) {
138         return -EIO;
139     }
140     
141     pnm_get(f, buf1, sizeof(buf1));
142     pnm_get(f, buf1, sizeof(buf1));
143     pnm_get(f, buf1, sizeof(buf1));
144     
145     picture[0] = buf;
146     get_buffer(f, picture[0], width * height*3);
147     
148     return 0;
149
150 }
151
152 static int yuv_read(VideoData *s, const char *filename, UINT8 *buf, int size1)
153 {
154     ByteIOContext pb1, *pb = &pb1;
155     char fname[1024], *p;
156     int size;
157
158     size = s->width * s->height;
159     
160     strcpy(fname, filename);
161     p = strrchr(fname, '.');
162     if (!p || p[1] != 'Y')
163         return -EIO;
164
165     if (url_fopen(pb, fname, URL_RDONLY) < 0)
166         return -EIO;
167     
168     get_buffer(pb, buf, size);
169     url_fclose(pb);
170     
171     p[1] = 'U';
172     if (url_fopen(pb, fname, URL_RDONLY) < 0)
173         return -EIO;
174
175     get_buffer(pb, buf + size, size / 4);
176     url_fclose(pb);
177     
178     p[1] = 'V';
179     if (url_fopen(pb, fname, URL_RDONLY) < 0)
180         return -EIO;
181
182     get_buffer(pb, buf + size + (size / 4), size / 4);
183     url_fclose(pb);
184     return 0;
185 }
186
187 static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
188 {
189     VideoData *s = s1->priv_data;
190     char filename[1024];
191     int ret;
192     ByteIOContext f1, *f;
193
194 /*
195     This if-statement destroys pipes - I do not see why it is necessary
196     if (get_frame_filename(filename, sizeof(filename),
197                            s->path, s->img_number) < 0)
198         return -EIO;
199 */
200     get_frame_filename(filename, sizeof(filename),
201                        s->path, s->img_number);
202     if (!s->is_pipe) {
203         f = &f1;
204         if (url_fopen(f, filename, URL_RDONLY) < 0)
205             return -EIO;
206     } else {
207         f = &s1->pb;
208         if (url_feof(f))
209             return -EIO;
210     }
211
212     av_new_packet(pkt, s->img_size);
213     pkt->stream_index = 0;
214
215     switch(s->img_fmt) {
216     case IMGFMT_PGMYUV:
217         ret = pgm_read(s, f, pkt->data, pkt->size, 1);
218         break;
219     case IMGFMT_PGM:
220         ret = pgm_read(s, f, pkt->data, pkt->size, 0);
221         break;
222     case IMGFMT_YUV:
223         ret = yuv_read(s, filename, pkt->data, pkt->size);
224         break;
225     case IMGFMT_PPM:
226         ret = ppm_read(s, f, pkt->data, pkt->size);
227         break;
228     default:
229         return -EIO;
230     }
231     
232     if (!s->is_pipe) {
233         url_fclose(f);
234     }
235
236     if (ret < 0) {
237         av_free_packet(pkt);
238         return -EIO; /* signal EOF */
239     } else {
240         s->img_number++;
241         return 0;
242     }
243 }
244
245 static int sizes[][2] = {
246     { 640, 480 },
247     { 720, 480 },
248     { 720, 576 },
249     { 352, 288 },
250     { 352, 240 },
251     { 160, 128 },
252     { 512, 384 },
253     { 640, 352 },
254     { 640, 240 },
255 };
256
257 static int infer_size(int *width_ptr, int *height_ptr, int size)
258 {
259     int i;
260
261     for(i=0;i<sizeof(sizes)/sizeof(sizes[0]);i++) {
262         if ((sizes[i][0] * sizes[i][1]) == size) {
263             *width_ptr = sizes[i][0];
264             *height_ptr = sizes[i][1];
265             return 0;
266         }
267     }
268     return -1;
269 }
270
271 static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap)
272 {
273     VideoData *s = s1->priv_data;
274     int i, h;
275     char buf[1024];
276     char buf1[32];
277     ByteIOContext pb1, *f = &pb1;
278     AVStream *st;
279
280     st = av_new_stream(s1, 0);
281     if (!st) {
282         av_free(s);
283         return -ENOMEM;
284     }
285
286     strcpy(s->path, s1->filename);
287     s->img_number = 0;
288
289     /* find format */
290     if (s1->iformat->flags & AVFMT_NOFILE)
291         s->is_pipe = 0;
292     else
293         s->is_pipe = 1;
294         
295     if (s1->iformat == &pgmyuvpipe_iformat ||
296         s1->iformat == &pgmyuv_iformat)
297         s->img_fmt = IMGFMT_PGMYUV;
298     else if (s1->iformat == &pgmpipe_iformat ||
299              s1->iformat == &pgm_iformat)
300         s->img_fmt = IMGFMT_PGM;
301     else if (s1->iformat == &imgyuv_iformat)
302         s->img_fmt = IMGFMT_YUV;
303     else if (s1->iformat == &ppmpipe_iformat ||
304              s1->iformat == &ppm_iformat)
305         s->img_fmt = IMGFMT_PPM;
306     else
307         goto fail;
308
309     if (!s->is_pipe) {
310         /* try to find the first image */
311         for(i=0;i<5;i++) {
312             if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0)
313                 goto fail;
314             if (url_fopen(f, buf, URL_RDONLY) >= 0)
315                 break;
316             s->img_number++;
317         }
318         if (i == 5)
319             goto fail;
320     } else {
321         f = &s1->pb;
322     }
323     
324     /* find the image size */
325     /* XXX: use generic file format guessing, as mpeg */
326     switch(s->img_fmt) {
327     case IMGFMT_PGM:
328     case IMGFMT_PGMYUV:
329     case IMGFMT_PPM:
330         pnm_get(f, buf1, sizeof(buf1));
331         pnm_get(f, buf1, sizeof(buf1));
332         s->width = atoi(buf1);
333         pnm_get(f, buf1, sizeof(buf1));
334         h = atoi(buf1);
335         if (s->img_fmt == IMGFMT_PGMYUV)
336             h = (h * 2) / 3;
337         s->height = h;
338         if (s->width <= 0 ||
339             s->height <= 0 ||
340             (s->width % 2) != 0 ||
341             (s->height % 2) != 0) {
342             goto fail1;
343         }
344         break;
345     case IMGFMT_YUV:
346         /* infer size by using the file size. */
347         {
348             int img_size;
349             URLContext *h;
350
351             /* XXX: hack hack */
352             h = url_fileno(f);
353             img_size = url_seek(h, 0, SEEK_END);
354             if (infer_size(&s->width, &s->height, img_size) < 0) {
355                 goto fail1;
356             }
357         }
358         break;
359     }
360     
361
362     if (!s->is_pipe) {
363         url_fclose(f);
364     } else {
365         url_fseek(f, 0, SEEK_SET);
366     }
367     
368
369     st->codec.codec_type = CODEC_TYPE_VIDEO;
370     st->codec.codec_id = CODEC_ID_RAWVIDEO;
371     st->codec.width = s->width;
372     st->codec.height = s->height;
373     if (s->img_fmt == IMGFMT_PPM) {
374         st->codec.pix_fmt = PIX_FMT_RGB24;
375         s->img_size = (s->width * s->height * 3);
376     } else {
377         st->codec.pix_fmt = PIX_FMT_YUV420P;
378         s->img_size = (s->width * s->height * 3) / 2;
379     }
380     if (!ap || !ap->frame_rate)
381         st->codec.frame_rate = 25 * FRAME_RATE_BASE;
382     else
383         st->codec.frame_rate = ap->frame_rate;
384     
385     return 0;
386  fail1:
387     if (!s->is_pipe)
388         url_fclose(f);
389  fail:
390     av_free(s);
391     return -EIO;
392 }
393
394 static int img_read_close(AVFormatContext *s1)
395 {
396     return 0;
397 }
398
399 /******************************************************/
400 /* image output */
401
402 static int pgm_save(AVPicture *picture, int width, int height, ByteIOContext *pb, int is_yuv) 
403 {
404     int i, h;
405     char buf[100];
406     UINT8 *ptr, *ptr1, *ptr2;
407
408     h = height;
409     if (is_yuv)
410         h = (height * 3) / 2;
411     snprintf(buf, sizeof(buf), 
412              "P5\n%d %d\n%d\n",
413              width, h, 255);
414     put_buffer(pb, buf, strlen(buf));
415     
416     ptr = picture->data[0];
417     for(i=0;i<height;i++) {
418         put_buffer(pb, ptr, width);
419         ptr += picture->linesize[0];
420     }
421
422     if (is_yuv) {
423         height >>= 1;
424         width >>= 1;
425         ptr1 = picture->data[1];
426         ptr2 = picture->data[2];
427         for(i=0;i<height;i++) {
428             put_buffer(pb, ptr1, width);
429             put_buffer(pb, ptr2, width);
430             ptr1 += picture->linesize[1];
431             ptr2 += picture->linesize[2];
432         }
433     }
434     put_flush_packet(pb);
435     return 0;
436 }
437
438 static int ppm_save(AVPicture *picture, int width, int height, ByteIOContext *pb) 
439 {
440     int i;
441     char buf[100];
442     UINT8 *ptr;
443
444     snprintf(buf, sizeof(buf), 
445              "P6\n%d %d\n%d\n",
446              width, height, 255);
447     put_buffer(pb, buf, strlen(buf));
448     
449     ptr = picture->data[0];
450     for(i=0;i<height;i++) {
451         put_buffer(pb, ptr, width * 3);
452         ptr += picture->linesize[0];
453     }
454
455     put_flush_packet(pb);
456     return 0;
457 }
458
459 static int yuv_save(AVPicture *picture, int width, int height, const char *filename)
460 {
461     ByteIOContext pb1, *pb = &pb1;
462     char fname[1024], *p;
463     int i, j;
464     UINT8 *ptr;
465     static char *ext = "YUV";
466
467     strcpy(fname, filename);
468     p = strrchr(fname, '.');
469     if (!p || p[1] != 'Y')
470         return -EIO;
471
472     for(i=0;i<3;i++) {
473         if (i == 1) {
474             width >>= 1;
475             height >>= 1;
476         }
477
478         p[1] = ext[i];
479         if (url_fopen(pb, fname, URL_WRONLY) < 0)
480             return -EIO;
481     
482         ptr = picture->data[i];
483         for(j=0;j<height;j++) {
484             put_buffer(pb, ptr, width);
485             ptr += picture->linesize[i];
486         }
487         put_flush_packet(pb);
488         url_fclose(pb);
489     }
490     return 0;
491 }
492
493 static int yuv4mpeg_save(AVPicture *picture, int width, int height, ByteIOContext *pb, int need_stream_header, 
494                         int is_yuv, int raten, int rated, int aspectn, int aspectd) 
495 {
496     int i, n, m;
497     char buf[Y4M_LINE_MAX+1], buf1[20];
498     UINT8 *ptr, *ptr1, *ptr2;
499     
500     /* construct stream header, if this is the first frame */
501     if(need_stream_header) {
502         n = snprintf(buf, sizeof(buf), "%s W%d H%d F%d:%d I%s A%d:%d\n",
503                 Y4M_MAGIC,
504                 width,
505                 height,
506                 raten, rated,
507                 "p",                    /* ffmpeg seems to only output progressive video */
508                 aspectn, aspectd);
509         if (n < 0) {
510             fprintf(stderr, "Error. YUV4MPEG stream header write failed.\n");
511         } else {
512             fprintf(stderr, "YUV4MPEG stream header written. FPS is %d\n", raten);
513             put_buffer(pb, buf, strlen(buf));
514         }
515     }
516     
517     /* construct frame header */
518     m = snprintf(buf1, sizeof(buf1), "%s \n", Y4M_FRAME_MAGIC);
519     if (m < 0) {
520         fprintf(stderr, "Error. YUV4MPEG frame header write failed.\n");
521     } else {
522         /* fprintf(stderr, "YUV4MPEG frame header written.\n"); */
523         put_buffer(pb, buf1, strlen(buf1));
524     }
525     
526     ptr = picture->data[0];
527     for(i=0;i<height;i++) {
528         put_buffer(pb, ptr, width);
529         ptr += picture->linesize[0];
530     }
531
532     if (is_yuv) {
533         height >>= 1;
534         width >>= 1;
535         ptr1 = picture->data[1];
536         ptr2 = picture->data[2];
537         for(i=0;i<height;i++) {         /* Cb */
538             put_buffer(pb, ptr1, width);
539             ptr1 += picture->linesize[1];
540         }
541          for(i=0;i<height;i++) {        /* Cr */
542             put_buffer(pb, ptr2, width);
543             ptr2 += picture->linesize[2];
544          }
545     }
546     put_flush_packet(pb);
547     return 0;
548 }
549
550 static int img_write_header(AVFormatContext *s)
551 {
552     VideoData *img = s->priv_data;
553
554     img->img_number = 1;
555     strcpy(img->path, s->filename);
556
557     /* find format */
558     if (s->oformat->flags & AVFMT_NOFILE)
559         img->is_pipe = 0;
560     else
561         img->is_pipe = 1;
562         
563     if (s->oformat == &pgmyuvpipe_oformat ||
564         s->oformat == &pgmyuv_oformat) {
565         img->img_fmt = IMGFMT_PGMYUV;
566     } else if (s->oformat == &pgmpipe_oformat ||
567                s->oformat == &pgm_oformat) {
568         img->img_fmt = IMGFMT_PGM;
569     } else if (s->oformat == &imgyuv_oformat) {
570         img->img_fmt = IMGFMT_YUV;
571     } else if (s->oformat == &ppmpipe_oformat ||
572                s->oformat == &ppm_oformat) {
573         img->img_fmt = IMGFMT_PPM;
574     } else if (s->oformat == &yuv4mpegpipe_oformat) {
575         img->img_fmt = IMGFMT_YUV4MPEG;
576         img->header_written = 0;    
577     } else {
578         goto fail;
579     }
580     return 0;
581  fail:
582     av_free(img);
583     return -EIO;
584 }
585
586 static int img_write_packet(AVFormatContext *s, int stream_index,
587                             UINT8 *buf, int size, int force_pts)
588 {
589     VideoData *img = s->priv_data;
590     AVStream *st = s->streams[stream_index];
591     ByteIOContext pb1, *pb;
592     AVPicture picture;
593     int width, height, need_stream_header, ret, size1, raten, rated, aspectn, aspectd, fps, fps1;
594     char filename[1024];
595
596     width = st->codec.width;
597     height = st->codec.height;
598     
599     if (img->img_number == 1) {
600         need_stream_header = 1;
601     } else {
602         need_stream_header = 0;
603     }
604     
605     fps = st->codec.frame_rate;
606     fps1 = (((float)fps / FRAME_RATE_BASE) * 1000);
607    
608    /* Sorry about this messy code, but mpeg2enc is very picky about
609     * the framerates it accepts. */
610     switch(fps1) {
611     case 23976:
612         raten = 24000; /* turn the framerate into a ratio */
613         rated = 1001;
614         break;
615     case 29970:
616         raten = 30000;
617         rated = 1001;
618         break;
619     case 25000:
620         raten = 25;
621         rated = 1;
622         break;
623     case 30000:
624         raten = 30;
625         rated = 1;
626         break;
627     case 24000:
628         raten = 24;
629         rated = 1;
630         break;
631     case 50000:
632         raten = 50;
633         rated = 1;
634         break;
635     case 59940:
636         raten = 60000;
637         rated = 1001;
638         break;
639     case 60000:
640         raten = 60;
641         rated = 1;
642         break;
643     default:
644         raten = fps1; /* this setting should work, but often doesn't */
645         rated = 1000;
646         break;
647     }
648     
649     aspectn = 1;
650     aspectd = 1;        /* ffmpeg always uses a 1:1 aspect ratio */
651
652     switch(st->codec.pix_fmt) {
653     case PIX_FMT_YUV420P:
654         size1 = (width * height * 3) / 2;
655         if (size != size1)
656             return -EIO;
657         
658         picture.data[0] = buf;
659         picture.data[1] = picture.data[0] + width * height;
660         picture.data[2] = picture.data[1] + (width * height) / 4;
661         picture.linesize[0] = width;
662         picture.linesize[1] = width >> 1; 
663         picture.linesize[2] = width >> 1;
664         break;
665     case PIX_FMT_RGB24:
666         size1 = (width * height * 3);
667         if (size != size1)
668             return -EIO;
669         picture.data[0] = buf;
670         picture.linesize[0] = width * 3;
671         break;
672     default:
673         return -EIO;
674     }
675     
676 /*
677     This if-statement destroys pipes - I do not see why it is necessary
678     if (get_frame_filename(filename, sizeof(filename), 
679                            img->path, img->img_number) < 0)
680         return -EIO;
681 */
682     get_frame_filename(filename, sizeof(filename), 
683                        img->path, img->img_number);
684     if (!img->is_pipe) {
685         pb = &pb1;
686         if (url_fopen(pb, filename, URL_WRONLY) < 0)
687             return -EIO;
688     } else {
689         pb = &s->pb;
690     }
691     switch(img->img_fmt) {
692     case IMGFMT_PGMYUV:
693         ret = pgm_save(&picture, width, height, pb, 1);
694         break;
695     case IMGFMT_PGM:
696         ret = pgm_save(&picture, width, height, pb, 0);
697         break;
698     case IMGFMT_YUV:
699         ret = yuv_save(&picture, width, height, filename);
700         break;
701     case IMGFMT_PPM:
702         ret = ppm_save(&picture, width, height, pb);
703         break;
704     case IMGFMT_YUV4MPEG:
705          ret = yuv4mpeg_save(&picture, width, height, pb,
706          need_stream_header, 1, raten, rated, aspectn, aspectd);
707         break;
708     }
709     if (!img->is_pipe) {
710         url_fclose(pb);
711     }
712
713     img->img_number++;
714     return 0;
715 }
716
717 static int img_write_trailer(AVFormatContext *s)
718 {
719     return 0;
720 }
721
722 AVInputFormat pgm_iformat = {
723     "pgm",
724     "pgm image format",
725     sizeof(VideoData),
726     NULL,
727     img_read_header,
728     img_read_packet,
729     img_read_close,
730     NULL,
731     AVFMT_NOFILE | AVFMT_NEEDNUMBER,
732     .extensions = "pgm",
733 };
734
735 AVOutputFormat pgm_oformat = {
736     "pgm",
737     "pgm image format",
738     "",
739     "pgm",
740     sizeof(VideoData),
741     CODEC_ID_NONE,
742     CODEC_ID_RAWVIDEO,
743     img_write_header,
744     img_write_packet,
745     img_write_trailer,
746     AVFMT_NOFILE | AVFMT_NEEDNUMBER,
747 };
748
749 AVInputFormat pgmyuv_iformat = {
750     "pgmyuv",
751     "pgm with YUV content image format",
752     sizeof(VideoData),
753     NULL, /* no probe */
754     img_read_header,
755     img_read_packet,
756     img_read_close,
757     NULL,
758     AVFMT_NOFILE | AVFMT_NEEDNUMBER,
759 };
760
761 AVOutputFormat pgmyuv_oformat = {
762     "pgmyuv",
763     "pgm with YUV content image format",
764     "",
765     "pgm",
766     sizeof(VideoData),
767     CODEC_ID_NONE,
768     CODEC_ID_RAWVIDEO,
769     img_write_header,
770     img_write_packet,
771     img_write_trailer,
772     AVFMT_NOFILE | AVFMT_NEEDNUMBER,
773 };
774
775 AVInputFormat ppm_iformat = {
776     "ppm",
777     "ppm image format",
778     sizeof(VideoData),
779     NULL,
780     img_read_header,
781     img_read_packet,
782     img_read_close,
783     NULL,
784     AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RGB24,
785     .extensions = "ppm",
786 };
787
788 AVOutputFormat ppm_oformat = {
789     "ppm",
790     "ppm image format",
791     "",
792     "ppm",
793     sizeof(VideoData),
794     CODEC_ID_NONE,
795     CODEC_ID_RAWVIDEO,
796     img_write_header,
797     img_write_packet,
798     img_write_trailer,
799     AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RGB24,
800 };
801
802 AVInputFormat imgyuv_iformat = {
803     ".Y.U.V",
804     ".Y.U.V format",
805     sizeof(VideoData),
806     NULL,
807     img_read_header,
808     img_read_packet,
809     img_read_close,
810     NULL,
811     AVFMT_NOFILE | AVFMT_NEEDNUMBER,
812     .extensions = "Y",
813 };
814
815 AVOutputFormat imgyuv_oformat = {
816     ".Y.U.V",
817     ".Y.U.V format",
818     "",
819     "Y",
820     sizeof(VideoData),
821     CODEC_ID_NONE,
822     CODEC_ID_RAWVIDEO,
823     img_write_header,
824     img_write_packet,
825     img_write_trailer,
826     AVFMT_NOFILE | AVFMT_NEEDNUMBER,
827 };
828
829 AVInputFormat pgmpipe_iformat = {
830     "pgmpipe",
831     "PGM pipe format",
832     sizeof(VideoData),
833     NULL, /* no probe */
834     img_read_header,
835     img_read_packet,
836     img_read_close,
837     NULL,
838 };
839
840 AVOutputFormat pgmpipe_oformat = {
841     "pgmpipe",
842     "PGM pipe format",
843     "",
844     "pgm",
845     sizeof(VideoData),
846     CODEC_ID_NONE,
847     CODEC_ID_RAWVIDEO,
848     img_write_header,
849     img_write_packet,
850     img_write_trailer,
851 };
852
853 AVInputFormat pgmyuvpipe_iformat = {
854     "pgmyuvpipe",
855     "PGM YUV pipe format",
856     sizeof(VideoData),
857     NULL, /* no probe */
858     img_read_header,
859     img_read_packet,
860     img_read_close,
861     NULL,
862 };
863
864 AVOutputFormat pgmyuvpipe_oformat = {
865     "pgmyuvpipe",
866     "PGM YUV pipe format",
867     "",
868     "pgm",
869     sizeof(VideoData),
870     CODEC_ID_NONE,
871     CODEC_ID_RAWVIDEO,
872     img_write_header,
873     img_write_packet,
874     img_write_trailer,
875 };
876
877 AVInputFormat ppmpipe_iformat = {
878     "ppmpipe",
879     "PPM pipe format",
880     sizeof(VideoData),
881     NULL, /* no probe */
882     img_read_header,
883     img_read_packet,
884     img_read_close,
885     NULL,
886     .flags = AVFMT_RGB24,
887 };
888
889 AVOutputFormat ppmpipe_oformat = {
890     "ppmpipe",
891     "PPM pipe format",
892     "",
893     "ppm",
894     sizeof(VideoData),
895     CODEC_ID_NONE,
896     CODEC_ID_RAWVIDEO,
897     img_write_header,
898     img_write_packet,
899     img_write_trailer,
900     .flags = AVFMT_RGB24,
901 };
902
903
904 AVOutputFormat yuv4mpegpipe_oformat = {
905     "yuv4mpegpipe",
906     "YUV4MPEG pipe format",
907     "",
908     "yuv4mpeg",
909     sizeof(VideoData),
910     CODEC_ID_NONE,
911     CODEC_ID_RAWVIDEO,
912     img_write_header,
913     img_write_packet,
914     img_write_trailer,
915 };
916
917
918 int img_init(void)
919 {
920     av_register_input_format(&pgm_iformat);
921     av_register_output_format(&pgm_oformat);
922
923     av_register_input_format(&pgmyuv_iformat);
924     av_register_output_format(&pgmyuv_oformat);
925
926     av_register_input_format(&ppm_iformat);
927     av_register_output_format(&ppm_oformat);
928
929     av_register_input_format(&imgyuv_iformat);
930     av_register_output_format(&imgyuv_oformat);
931     
932     av_register_input_format(&pgmpipe_iformat);
933     av_register_output_format(&pgmpipe_oformat);
934
935     av_register_input_format(&pgmyuvpipe_iformat);
936     av_register_output_format(&pgmyuvpipe_oformat);
937
938     av_register_input_format(&ppmpipe_iformat);
939     av_register_output_format(&ppmpipe_oformat);
940        
941     av_register_output_format(&yuv4mpegpipe_oformat);
942     
943     return 0;
944 }