3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4 * Copyright (c) 2004 Michael Niedermayer
6 * This file is part of FFmpeg.
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.
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.
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
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/avstring.h"
42 static const IdStrMap img_tags
[] = {
43 { CODEC_ID_MJPEG
, "jpeg"},
44 { CODEC_ID_MJPEG
, "jpg"},
45 { CODEC_ID_LJPEG
, "ljpg"},
46 { CODEC_ID_PNG
, "png"},
47 { CODEC_ID_PNG
, "mng"},
48 { CODEC_ID_PPM
, "ppm"},
49 { CODEC_ID_PPM
, "pnm"},
50 { CODEC_ID_PGM
, "pgm"},
51 { CODEC_ID_PGMYUV
, "pgmyuv"},
52 { CODEC_ID_PBM
, "pbm"},
53 { CODEC_ID_PAM
, "pam"},
54 { CODEC_ID_MPEG1VIDEO
, "mpg1-img"},
55 { CODEC_ID_MPEG2VIDEO
, "mpg2-img"},
56 { CODEC_ID_MPEG4
, "mpg4-img"},
57 { CODEC_ID_FFV1
, "ffv1-img"},
58 { CODEC_ID_RAWVIDEO
, "y"},
59 { CODEC_ID_BMP
, "bmp"},
60 { CODEC_ID_GIF
, "gif"},
61 { CODEC_ID_TARGA
, "tga"},
62 { CODEC_ID_TIFF
, "tiff"},
63 { CODEC_ID_TIFF
, "tif"},
64 { CODEC_ID_SGI
, "sgi"},
65 { CODEC_ID_PTX
, "ptx"},
66 { CODEC_ID_PCX
, "pcx"},
67 { CODEC_ID_SUNRAST
, "sun"},
68 { CODEC_ID_SUNRAST
, "ras"},
69 { CODEC_ID_SUNRAST
, "rs"},
70 { CODEC_ID_SUNRAST
, "im1"},
71 { CODEC_ID_SUNRAST
, "im8"},
72 { CODEC_ID_SUNRAST
, "im24"},
73 { CODEC_ID_SUNRAST
, "sunras"},
74 { CODEC_ID_JPEG2000
, "jp2"},
75 { CODEC_ID_DPX
, "dpx"},
76 { CODEC_ID_NONE
, NULL
}
79 static const int sizes
[][2] = {
91 static int infer_size(int *width_ptr
, int *height_ptr
, int size
)
95 for(i
=0;i
<FF_ARRAY_ELEMS(sizes
);i
++) {
96 if ((sizes
[i
][0] * sizes
[i
][1]) == size
) {
97 *width_ptr
= sizes
[i
][0];
98 *height_ptr
= sizes
[i
][1];
104 static enum CodecID
av_str2id(const IdStrMap
*tags
, const char *str
)
106 str
= strrchr(str
, '.');
107 if(!str
) return CODEC_ID_NONE
;
111 if (!strcasecmp(str
, tags
->str
))
116 return CODEC_ID_NONE
;
119 /* return -1 if no image found */
120 static int find_image_range(int *pfirst_index
, int *plast_index
,
124 int range
, last_index
, range1
, first_index
;
126 /* find the first image */
127 for(first_index
= 0; first_index
< 5; first_index
++) {
128 if (av_get_frame_filename(buf
, sizeof(buf
), path
, first_index
) < 0){
138 if (first_index
== 5)
141 /* find the last image */
142 last_index
= first_index
;
150 if (av_get_frame_filename(buf
, sizeof(buf
), path
,
151 last_index
+ range1
) < 0)
156 /* just in case... */
157 if (range
>= (1 << 30))
160 /* we are sure than image last_index + range exists */
165 *pfirst_index
= first_index
;
166 *plast_index
= last_index
;
173 static int image_probe(AVProbeData
*p
)
175 if (p
->filename
&& av_str2id(img_tags
, p
->filename
)) {
176 if (av_filename_number_test(p
->filename
))
177 return AVPROBE_SCORE_MAX
;
179 return AVPROBE_SCORE_MAX
/2;
184 enum CodecID
av_guess_image2_codec(const char *filename
){
185 return av_str2id(img_tags
, filename
);
188 static int img_read_header(AVFormatContext
*s1
, AVFormatParameters
*ap
)
190 VideoData
*s
= s1
->priv_data
;
191 int first_index
, last_index
;
194 s1
->ctx_flags
|= AVFMTCTX_NOHEADER
;
196 st
= av_new_stream(s1
, 0);
198 return AVERROR(ENOMEM
);
201 av_strlcpy(s
->path
, s1
->filename
, sizeof(s
->path
));
206 if (s1
->iformat
->flags
& AVFMT_NOFILE
)
210 st
->need_parsing
= AVSTREAM_PARSE_FULL
;
213 if (!ap
->time_base
.num
) {
214 av_set_pts_info(st
, 60, 1, 25);
216 av_set_pts_info(st
, 60, ap
->time_base
.num
, ap
->time_base
.den
);
219 if(ap
->width
&& ap
->height
){
220 st
->codec
->width
= ap
->width
;
221 st
->codec
->height
= ap
->height
;
225 if (find_image_range(&first_index
, &last_index
, s
->path
) < 0)
226 return AVERROR(ENOENT
);
227 s
->img_first
= first_index
;
228 s
->img_last
= last_index
;
229 s
->img_number
= first_index
;
230 /* compute duration */
232 st
->duration
= last_index
- first_index
+ 1;
235 if(ap
->video_codec_id
){
236 st
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
237 st
->codec
->codec_id
= ap
->video_codec_id
;
238 }else if(ap
->audio_codec_id
){
239 st
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
240 st
->codec
->codec_id
= ap
->audio_codec_id
;
242 st
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
243 st
->codec
->codec_id
= av_str2id(img_tags
, s
->path
);
245 if(st
->codec
->codec_type
== CODEC_TYPE_VIDEO
&& ap
->pix_fmt
!= PIX_FMT_NONE
)
246 st
->codec
->pix_fmt
= ap
->pix_fmt
;
251 static int img_read_packet(AVFormatContext
*s1
, AVPacket
*pkt
)
253 VideoData
*s
= s1
->priv_data
;
256 int size
[3]={0}, ret
[3]={0};
258 AVCodecContext
*codec
= s1
->streams
[0]->codec
;
261 /* loop over input */
262 if (s1
->loop_input
&& s
->img_number
> s
->img_last
) {
263 s
->img_number
= s
->img_first
;
265 if (s
->img_number
> s
->img_last
)
267 if (av_get_frame_filename(filename
, sizeof(filename
),
268 s
->path
, s
->img_number
)<0 && s
->img_number
> 1)
271 if (url_fopen(&f
[i
], filename
, URL_RDONLY
) < 0) {
272 av_log(s1
, AV_LOG_ERROR
, "Could not open file : %s\n",filename
);
275 size
[i
]= url_fsize(f
[i
]);
277 if(codec
->codec_id
!= CODEC_ID_RAWVIDEO
)
279 filename
[ strlen(filename
) - 1 ]= 'U' + i
;
282 if(codec
->codec_id
== CODEC_ID_RAWVIDEO
&& !codec
->width
)
283 infer_size(&codec
->width
, &codec
->height
, size
[0]);
291 av_new_packet(pkt
, size
[0] + size
[1] + size
[2]);
292 pkt
->stream_index
= 0;
293 pkt
->flags
|= PKT_FLAG_KEY
;
298 ret
[i
]= get_buffer(f
[i
], pkt
->data
+ pkt
->size
, size
[i
]);
306 if (ret
[0] <= 0 || ret
[1]<0 || ret
[2]<0) {
308 return AVERROR(EIO
); /* signal EOF */
316 #if CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER
317 /******************************************************/
320 static int img_write_header(AVFormatContext
*s
)
322 VideoData
*img
= s
->priv_data
;
325 av_strlcpy(img
->path
, s
->filename
, sizeof(img
->path
));
328 if (s
->oformat
->flags
& AVFMT_NOFILE
)
336 static int img_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
338 VideoData
*img
= s
->priv_data
;
339 ByteIOContext
*pb
[3];
341 AVCodecContext
*codec
= s
->streams
[ pkt
->stream_index
]->codec
;
345 if (av_get_frame_filename(filename
, sizeof(filename
),
346 img
->path
, img
->img_number
) < 0 && img
->img_number
>1)
349 if (url_fopen(&pb
[i
], filename
, URL_WRONLY
) < 0) {
350 av_log(s
, AV_LOG_ERROR
, "Could not open file : %s\n",filename
);
354 if(codec
->codec_id
!= CODEC_ID_RAWVIDEO
)
356 filename
[ strlen(filename
) - 1 ]= 'U' + i
;
362 if(codec
->codec_id
== CODEC_ID_RAWVIDEO
){
363 int ysize
= codec
->width
* codec
->height
;
364 put_buffer(pb
[0], pkt
->data
, ysize
);
365 put_buffer(pb
[1], pkt
->data
+ ysize
, (pkt
->size
- ysize
)/2);
366 put_buffer(pb
[2], pkt
->data
+ ysize
+(pkt
->size
- ysize
)/2, (pkt
->size
- ysize
)/2);
367 put_flush_packet(pb
[1]);
368 put_flush_packet(pb
[2]);
372 if(av_str2id(img_tags
, s
->filename
) == CODEC_ID_JPEG2000
){
373 AVStream
*st
= s
->streams
[0];
374 if(st
->codec
->extradata_size
> 8 &&
375 AV_RL32(st
->codec
->extradata
+4) == MKTAG('j','p','2','h')){
376 if(pkt
->size
< 8 || AV_RL32(pkt
->data
+4) != MKTAG('j','p','2','c'))
379 put_tag (pb
[0], "jP ");
380 put_be32(pb
[0], 0x0D0A870A); // signature
382 put_tag (pb
[0], "ftyp");
383 put_tag (pb
[0], "jp2 ");
385 put_tag (pb
[0], "jp2 ");
386 put_buffer(pb
[0], st
->codec
->extradata
, st
->codec
->extradata_size
);
387 }else if(pkt
->size
< 8 ||
388 (!st
->codec
->extradata_size
&&
389 AV_RL32(pkt
->data
+4) != MKTAG('j','P',' ',' '))){ // signature
391 av_log(s
, AV_LOG_ERROR
, "malformated jpeg2000 codestream\n");
395 put_buffer(pb
[0], pkt
->data
, pkt
->size
);
397 put_flush_packet(pb
[0]);
406 #endif /* CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER */
409 #if CONFIG_IMAGE2_DEMUXER
410 AVInputFormat image2_demuxer
= {
412 NULL_IF_CONFIG_SMALL("image2 sequence"),
423 #if CONFIG_IMAGE2PIPE_DEMUXER
424 AVInputFormat image2pipe_demuxer
= {
426 NULL_IF_CONFIG_SMALL("piped image2 sequence"),
435 #if CONFIG_IMAGE2_MUXER
436 AVOutputFormat image2_muxer
= {
438 NULL_IF_CONFIG_SMALL("image2 sequence"),
440 "bmp,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,ppm,sgi,tif,tiff,jp2",
447 .flags
= AVFMT_NOTIMESTAMPS
| AVFMT_NOFILE
450 #if CONFIG_IMAGE2PIPE_MUXER
451 AVOutputFormat image2pipe_muxer
= {
453 NULL_IF_CONFIG_SMALL("piped image2 sequence"),
461 .flags
= AVFMT_NOTIMESTAMPS