]> git.sesse.net Git - ffmpeg/blob - libavformat/img2.c
Merge remote branch 'qatar/master'
[ffmpeg] / libavformat / img2.c
1 /*
2  * Image format
3  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4  * Copyright (c) 2004 Michael Niedermayer
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg 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  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/avstring.h"
25 #include "avformat.h"
26 #include "avio_internal.h"
27 #include "internal.h"
28 #include <strings.h>
29
30 typedef struct {
31     int img_first;
32     int img_last;
33     int img_number;
34     int img_count;
35     int is_pipe;
36     int split_planes;  /**< use independent file for each Y, U, V plane */
37     char path[1024];
38 } VideoData;
39
40 typedef struct {
41     enum CodecID id;
42     const char *str;
43 } IdStrMap;
44
45 static const IdStrMap img_tags[] = {
46     { CODEC_ID_MJPEG     , "jpeg"},
47     { CODEC_ID_MJPEG     , "jpg"},
48     { CODEC_ID_LJPEG     , "ljpg"},
49     { CODEC_ID_PNG       , "png"},
50     { CODEC_ID_PNG       , "mng"},
51     { CODEC_ID_PPM       , "ppm"},
52     { CODEC_ID_PPM       , "pnm"},
53     { CODEC_ID_PGM       , "pgm"},
54     { CODEC_ID_PGMYUV    , "pgmyuv"},
55     { CODEC_ID_PBM       , "pbm"},
56     { CODEC_ID_PAM       , "pam"},
57     { CODEC_ID_MPEG1VIDEO, "mpg1-img"},
58     { CODEC_ID_MPEG2VIDEO, "mpg2-img"},
59     { CODEC_ID_MPEG4     , "mpg4-img"},
60     { CODEC_ID_FFV1      , "ffv1-img"},
61     { CODEC_ID_RAWVIDEO  , "y"},
62     { CODEC_ID_RAWVIDEO  , "raw"},
63     { CODEC_ID_BMP       , "bmp"},
64     { CODEC_ID_GIF       , "gif"},
65     { CODEC_ID_TARGA     , "tga"},
66     { CODEC_ID_TIFF      , "tiff"},
67     { CODEC_ID_TIFF      , "tif"},
68     { CODEC_ID_SGI       , "sgi"},
69     { CODEC_ID_PTX       , "ptx"},
70     { CODEC_ID_PCX       , "pcx"},
71     { CODEC_ID_SUNRAST   , "sun"},
72     { CODEC_ID_SUNRAST   , "ras"},
73     { CODEC_ID_SUNRAST   , "rs"},
74     { CODEC_ID_SUNRAST   , "im1"},
75     { CODEC_ID_SUNRAST   , "im8"},
76     { CODEC_ID_SUNRAST   , "im24"},
77     { CODEC_ID_SUNRAST   , "sunras"},
78     { CODEC_ID_JPEG2000  , "jp2"},
79     { CODEC_ID_DPX       , "dpx"},
80     { CODEC_ID_PICTOR    , "pic"},
81     { CODEC_ID_NONE      , NULL}
82 };
83
84 static const int sizes[][2] = {
85     { 640, 480 },
86     { 720, 480 },
87     { 720, 576 },
88     { 352, 288 },
89     { 352, 240 },
90     { 160, 128 },
91     { 512, 384 },
92     { 640, 352 },
93     { 640, 240 },
94 };
95
96 static int infer_size(int *width_ptr, int *height_ptr, int size)
97 {
98     int i;
99
100     for(i=0;i<FF_ARRAY_ELEMS(sizes);i++) {
101         if ((sizes[i][0] * sizes[i][1]) == size) {
102             *width_ptr = sizes[i][0];
103             *height_ptr = sizes[i][1];
104             return 0;
105         }
106     }
107     return -1;
108 }
109 static enum CodecID av_str2id(const IdStrMap *tags, const char *str)
110 {
111     str= strrchr(str, '.');
112     if(!str) return CODEC_ID_NONE;
113     str++;
114
115     while (tags->id) {
116         if (!strcasecmp(str, tags->str))
117             return tags->id;
118
119         tags++;
120     }
121     return CODEC_ID_NONE;
122 }
123
124 /* return -1 if no image found */
125 static int find_image_range(int *pfirst_index, int *plast_index,
126                             const char *path)
127 {
128     char buf[1024];
129     int range, last_index, range1, first_index;
130
131     /* find the first image */
132     for(first_index = 0; first_index < 5; first_index++) {
133         if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0){
134             *pfirst_index =
135             *plast_index = 1;
136             if(url_exist(buf))
137                 return 0;
138             return -1;
139         }
140         if (url_exist(buf))
141             break;
142     }
143     if (first_index == 5)
144         goto fail;
145
146     /* find the last image */
147     last_index = first_index;
148     for(;;) {
149         range = 0;
150         for(;;) {
151             if (!range)
152                 range1 = 1;
153             else
154                 range1 = 2 * range;
155             if (av_get_frame_filename(buf, sizeof(buf), path,
156                                       last_index + range1) < 0)
157                 goto fail;
158             if (!url_exist(buf))
159                 break;
160             range = range1;
161             /* just in case... */
162             if (range >= (1 << 30))
163                 goto fail;
164         }
165         /* we are sure than image last_index + range exists */
166         if (!range)
167             break;
168         last_index += range;
169     }
170     *pfirst_index = first_index;
171     *plast_index = last_index;
172     return 0;
173  fail:
174     return -1;
175 }
176
177
178 static int read_probe(AVProbeData *p)
179 {
180     if (p->filename && av_str2id(img_tags, p->filename)) {
181         if (av_filename_number_test(p->filename))
182             return AVPROBE_SCORE_MAX;
183         else
184             return AVPROBE_SCORE_MAX/2;
185     }
186     return 0;
187 }
188
189 enum CodecID ff_guess_image2_codec(const char *filename)
190 {
191     return av_str2id(img_tags, filename);
192 }
193
194 #if FF_API_GUESS_IMG2_CODEC
195 enum CodecID av_guess_image2_codec(const char *filename){
196     return av_str2id(img_tags, filename);
197 }
198 #endif
199
200 static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
201 {
202     VideoData *s = s1->priv_data;
203     int first_index, last_index;
204     AVStream *st;
205
206     s1->ctx_flags |= AVFMTCTX_NOHEADER;
207
208     st = av_new_stream(s1, 0);
209     if (!st) {
210         return AVERROR(ENOMEM);
211     }
212
213     av_strlcpy(s->path, s1->filename, sizeof(s->path));
214     s->img_number = 0;
215     s->img_count = 0;
216
217     /* find format */
218     if (s1->iformat->flags & AVFMT_NOFILE)
219         s->is_pipe = 0;
220     else{
221         s->is_pipe = 1;
222         st->need_parsing = AVSTREAM_PARSE_FULL;
223     }
224
225     if (!ap->time_base.num) {
226         av_set_pts_info(st, 60, 1, 25);
227     } else {
228         av_set_pts_info(st, 60, ap->time_base.num, ap->time_base.den);
229     }
230
231     if(ap->width && ap->height){
232         st->codec->width = ap->width;
233         st->codec->height= ap->height;
234     }
235
236     if (!s->is_pipe) {
237         if (find_image_range(&first_index, &last_index, s->path) < 0)
238             return AVERROR(ENOENT);
239         s->img_first = first_index;
240         s->img_last = last_index;
241         s->img_number = first_index;
242         /* compute duration */
243         st->start_time = 0;
244         st->duration = last_index - first_index + 1;
245     }
246
247     if(s1->video_codec_id){
248         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
249         st->codec->codec_id = s1->video_codec_id;
250     }else if(s1->audio_codec_id){
251         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
252         st->codec->codec_id = s1->audio_codec_id;
253     }else{
254         const char *str= strrchr(s->path, '.');
255         s->split_planes = str && !strcasecmp(str + 1, "y");
256         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
257         st->codec->codec_id = av_str2id(img_tags, s->path);
258     }
259     if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ap->pix_fmt != PIX_FMT_NONE)
260         st->codec->pix_fmt = ap->pix_fmt;
261
262     return 0;
263 }
264
265 static int read_packet(AVFormatContext *s1, AVPacket *pkt)
266 {
267     VideoData *s = s1->priv_data;
268     char filename[1024];
269     int i;
270     int size[3]={0}, ret[3]={0};
271     AVIOContext *f[3];
272     AVCodecContext *codec= s1->streams[0]->codec;
273
274     if (!s->is_pipe) {
275         /* loop over input */
276         if (s1->loop_input && s->img_number > s->img_last) {
277             s->img_number = s->img_first;
278         }
279         if (s->img_number > s->img_last)
280             return AVERROR_EOF;
281         if (av_get_frame_filename(filename, sizeof(filename),
282                                   s->path, s->img_number)<0 && s->img_number > 1)
283             return AVERROR(EIO);
284         for(i=0; i<3; i++){
285             if (avio_open(&f[i], filename, AVIO_RDONLY) < 0) {
286                 if(i==1)
287                     break;
288                 av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n",filename);
289                 return AVERROR(EIO);
290             }
291             size[i]= avio_size(f[i]);
292
293             if(!s->split_planes)
294                 break;
295             filename[ strlen(filename) - 1 ]= 'U' + i;
296         }
297
298         if(codec->codec_id == CODEC_ID_RAWVIDEO && !codec->width)
299             infer_size(&codec->width, &codec->height, size[0]);
300     } else {
301         f[0] = s1->pb;
302         if (url_feof(f[0]))
303             return AVERROR(EIO);
304         size[0]= 4096;
305     }
306
307     av_new_packet(pkt, size[0] + size[1] + size[2]);
308     pkt->stream_index = 0;
309     pkt->flags |= AV_PKT_FLAG_KEY;
310
311     pkt->size= 0;
312     for(i=0; i<3; i++){
313         if(size[i]){
314             ret[i]= avio_read(f[i], pkt->data + pkt->size, size[i]);
315             if (!s->is_pipe)
316                 avio_close(f[i]);
317             if(ret[i]>0)
318                 pkt->size += ret[i];
319         }
320     }
321
322     if (ret[0] <= 0 || ret[1]<0 || ret[2]<0) {
323         av_free_packet(pkt);
324         return AVERROR(EIO); /* signal EOF */
325     } else {
326         s->img_count++;
327         s->img_number++;
328         return 0;
329     }
330 }
331
332 #if CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER
333 /******************************************************/
334 /* image output */
335
336 static int write_header(AVFormatContext *s)
337 {
338     VideoData *img = s->priv_data;
339     const char *str;
340
341     img->img_number = 1;
342     av_strlcpy(img->path, s->filename, sizeof(img->path));
343
344     /* find format */
345     if (s->oformat->flags & AVFMT_NOFILE)
346         img->is_pipe = 0;
347     else
348         img->is_pipe = 1;
349
350     str = strrchr(img->path, '.');
351     img->split_planes = str && !strcasecmp(str + 1, "y");
352     return 0;
353 }
354
355 static int write_packet(AVFormatContext *s, AVPacket *pkt)
356 {
357     VideoData *img = s->priv_data;
358     AVIOContext *pb[3];
359     char filename[1024];
360     AVCodecContext *codec= s->streams[ pkt->stream_index ]->codec;
361     int i;
362
363     if (!img->is_pipe) {
364         if (av_get_frame_filename(filename, sizeof(filename),
365                                   img->path, img->img_number) < 0 && img->img_number>1) {
366             av_log(s, AV_LOG_ERROR,
367                    "Could not get frame filename number %d from pattern '%s'\n",
368                    img->img_number, img->path);
369             return AVERROR(EIO);
370         }
371         for(i=0; i<3; i++){
372             if (avio_open(&pb[i], filename, AVIO_WRONLY) < 0) {
373                 av_log(s, AV_LOG_ERROR, "Could not open file : %s\n",filename);
374                 return AVERROR(EIO);
375             }
376
377             if(!img->split_planes)
378                 break;
379             filename[ strlen(filename) - 1 ]= 'U' + i;
380         }
381     } else {
382         pb[0] = s->pb;
383     }
384
385     if(img->split_planes){
386         int ysize = codec->width * codec->height;
387         avio_write(pb[0], pkt->data        , ysize);
388         avio_write(pb[1], pkt->data + ysize, (pkt->size - ysize)/2);
389         avio_write(pb[2], pkt->data + ysize +(pkt->size - ysize)/2, (pkt->size - ysize)/2);
390         avio_flush(pb[1]);
391         avio_flush(pb[2]);
392         avio_close(pb[1]);
393         avio_close(pb[2]);
394     }else{
395         if(av_str2id(img_tags, s->filename) == CODEC_ID_JPEG2000){
396             AVStream *st = s->streams[0];
397             if(st->codec->extradata_size > 8 &&
398                AV_RL32(st->codec->extradata+4) == MKTAG('j','p','2','h')){
399                 if(pkt->size < 8 || AV_RL32(pkt->data+4) != MKTAG('j','p','2','c'))
400                     goto error;
401                 avio_wb32(pb[0], 12);
402                 ffio_wfourcc(pb[0], "jP  ");
403                 avio_wb32(pb[0], 0x0D0A870A); // signature
404                 avio_wb32(pb[0], 20);
405                 ffio_wfourcc(pb[0], "ftyp");
406                 ffio_wfourcc(pb[0], "jp2 ");
407                 avio_wb32(pb[0], 0);
408                 ffio_wfourcc(pb[0], "jp2 ");
409                 avio_write(pb[0], st->codec->extradata, st->codec->extradata_size);
410             }else if(pkt->size < 8 ||
411                      (!st->codec->extradata_size &&
412                       AV_RL32(pkt->data+4) != MKTAG('j','P',' ',' '))){ // signature
413             error:
414                 av_log(s, AV_LOG_ERROR, "malformated jpeg2000 codestream\n");
415                 return -1;
416             }
417         }
418         avio_write(pb[0], pkt->data, pkt->size);
419     }
420     avio_flush(pb[0]);
421     if (!img->is_pipe) {
422         avio_close(pb[0]);
423     }
424
425     img->img_number++;
426     return 0;
427 }
428
429 #endif /* CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER */
430
431 /* input */
432 #if CONFIG_IMAGE2_DEMUXER
433 AVInputFormat ff_image2_demuxer = {
434     .name           = "image2",
435     .long_name      = NULL_IF_CONFIG_SMALL("image2 sequence"),
436     .priv_data_size = sizeof(VideoData),
437     .read_probe     = read_probe,
438     .read_header    = read_header,
439     .read_packet    = read_packet,
440     .flags          = AVFMT_NOFILE,
441 };
442 #endif
443 #if CONFIG_IMAGE2PIPE_DEMUXER
444 AVInputFormat ff_image2pipe_demuxer = {
445     .name           = "image2pipe",
446     .long_name      = NULL_IF_CONFIG_SMALL("piped image2 sequence"),
447     .priv_data_size = sizeof(VideoData),
448     .read_header    = read_header,
449     .read_packet    = read_packet,
450 };
451 #endif
452
453 /* output */
454 #if CONFIG_IMAGE2_MUXER
455 AVOutputFormat ff_image2_muxer = {
456     .name           = "image2",
457     .long_name      = NULL_IF_CONFIG_SMALL("image2 sequence"),
458     .extensions     = "bmp,dpx,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
459                       "ppm,sgi,tga,tif,tiff,jp2",
460     .priv_data_size = sizeof(VideoData),
461     .video_codec    = CODEC_ID_MJPEG,
462     .write_header   = write_header,
463     .write_packet   = write_packet,
464     .flags          = AVFMT_NOTIMESTAMPS | AVFMT_NODIMENSIONS | AVFMT_NOFILE
465 };
466 #endif
467 #if CONFIG_IMAGE2PIPE_MUXER
468 AVOutputFormat ff_image2pipe_muxer = {
469     .name           = "image2pipe",
470     .long_name      = NULL_IF_CONFIG_SMALL("piped image2 sequence"),
471     .priv_data_size = sizeof(VideoData),
472     .video_codec    = CODEC_ID_MJPEG,
473     .write_header   = write_header,
474     .write_packet   = write_packet,
475     .flags          = AVFMT_NOTIMESTAMPS | AVFMT_NODIMENSIONS
476 };
477 #endif