Originally committed as revision 128 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -169,7 +169,9 @@ static int img_read_packet(AVFormatContext *s1, AVPacket *pkt) | |||
| int ret; | |||
| ByteIOContext f1, *f; | |||
| snprintf(filename, sizeof(filename), s->path, s->img_number); | |||
| if (get_frame_filename(filename, sizeof(filename), | |||
| s->path, s->img_number) < 0) | |||
| return -EIO; | |||
| if (!s->is_pipe) { | |||
| f = &f1; | |||
| @@ -223,6 +225,7 @@ static int sizes[][2] = { | |||
| { 160, 128 }, | |||
| { 512, 384 }, | |||
| { 640, 352 }, | |||
| { 640, 240 }, | |||
| }; | |||
| static int infer_size(int *width_ptr, int *height_ptr, int size) | |||
| @@ -288,7 +291,8 @@ static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |||
| if (!s->is_pipe) { | |||
| /* try to find the first image */ | |||
| for(i=0;i<5;i++) { | |||
| snprintf(buf, sizeof(buf), s->path, s->img_number); | |||
| if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0) | |||
| goto fail; | |||
| if (url_fopen(f, buf, URL_RDONLY) >= 0) | |||
| break; | |||
| s->img_number++; | |||
| @@ -543,7 +547,9 @@ static int img_write_packet(AVFormatContext *s, int stream_index, | |||
| return -EIO; | |||
| } | |||
| snprintf(filename, sizeof(filename), img->path, img->img_number); | |||
| if (get_frame_filename(filename, sizeof(filename), | |||
| img->path, img->img_number) < 0) | |||
| return -EIO; | |||
| if (!img->is_pipe) { | |||
| pb = &pb1; | |||
| @@ -596,7 +602,7 @@ AVFormat pgm_format = { | |||
| img_read_packet, | |||
| img_read_close, | |||
| NULL, | |||
| AVFMT_NOFILE, | |||
| AVFMT_NOFILE | AVFMT_NEEDNUMBER, | |||
| }; | |||
| AVFormat pgmyuv_format = { | |||
| @@ -614,7 +620,7 @@ AVFormat pgmyuv_format = { | |||
| img_read_packet, | |||
| img_read_close, | |||
| NULL, | |||
| AVFMT_NOFILE, | |||
| AVFMT_NOFILE | AVFMT_NEEDNUMBER, | |||
| }; | |||
| AVFormat ppm_format = { | |||
| @@ -632,7 +638,7 @@ AVFormat ppm_format = { | |||
| img_read_packet, | |||
| img_read_close, | |||
| NULL, | |||
| AVFMT_NOFILE, | |||
| AVFMT_NOFILE | AVFMT_NEEDNUMBER, | |||
| }; | |||
| AVFormat imgyuv_format = { | |||
| @@ -650,7 +656,7 @@ AVFormat imgyuv_format = { | |||
| img_read_packet, | |||
| img_read_close, | |||
| NULL, | |||
| AVFMT_NOFILE, | |||
| AVFMT_NOFILE | AVFMT_NEEDNUMBER, | |||
| }; | |||
| AVFormat pgmpipe_format = { | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Miscellaneous MJPEG based formats | |||
| * Copyright (c) 2000 Gerard Lantau. | |||
| * JPEG based formats | |||
| * Copyright (c) 2000, 2001 Gerard Lantau. | |||
| * | |||
| * This program is free software; you can redistribute it and/or modify | |||
| * it under the terms of the GNU General Public License as published by | |||
| @@ -126,7 +126,9 @@ static int jpeg_write_packet(AVFormatContext *s1, int stream_index, | |||
| char filename[1024]; | |||
| ByteIOContext f1, *pb = &f1; | |||
| snprintf(filename, sizeof(filename), s->path, s->img_number); | |||
| if (get_frame_filename(filename, sizeof(filename), | |||
| s->path, s->img_number) < 0) | |||
| return -EIO; | |||
| if (url_fopen(pb, filename, URL_WRONLY) < 0) | |||
| return -EIO; | |||
| @@ -173,7 +175,8 @@ static int jpeg_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |||
| /* try to find the first image */ | |||
| for(i=0;i<5;i++) { | |||
| snprintf(buf, sizeof(buf), s->path, s->img_number); | |||
| if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0) | |||
| goto fail; | |||
| if (url_fopen(f, buf, URL_RDONLY) >= 0) | |||
| break; | |||
| s->img_number++; | |||
| @@ -201,7 +204,9 @@ static int jpeg_read_packet(AVFormatContext *s1, AVPacket *pkt) | |||
| int size; | |||
| ByteIOContext f1, *f = &f1; | |||
| snprintf(filename, sizeof(filename), s->path, s->img_number); | |||
| if (get_frame_filename(filename, sizeof(filename), | |||
| s->path, s->img_number) < 0) | |||
| return -EIO; | |||
| f = &f1; | |||
| if (url_fopen(f, filename, URL_RDONLY) < 0) | |||
| @@ -241,5 +246,5 @@ AVFormat jpeg_format = { | |||
| jpeg_read_packet, | |||
| jpeg_read_close, | |||
| NULL, | |||
| AVFMT_NOFILE, | |||
| AVFMT_NOFILE | AVFMT_NEEDNUMBER, | |||
| }; | |||
| @@ -548,3 +548,59 @@ int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info) | |||
| return 0; | |||
| } | |||
| /* Return in 'buf' the path with '%d' replaced by number. Also handles | |||
| the '%0nd' format where 'n' is the total number of digits and | |||
| '%%'. Return 0 if OK, and -1 if format error */ | |||
| int get_frame_filename(char *buf, int buf_size, | |||
| const char *path, int number) | |||
| { | |||
| const char *p; | |||
| char *q, buf1[20]; | |||
| int nd, len, c, percentd_found; | |||
| q = buf; | |||
| p = path; | |||
| percentd_found = 0; | |||
| for(;;) { | |||
| c = *p++; | |||
| if (c == '\0') | |||
| break; | |||
| if (c == '%') { | |||
| nd = 0; | |||
| while (*p >= '0' && *p <= '9') { | |||
| nd = nd * 10 + *p++ - '0'; | |||
| } | |||
| c = *p++; | |||
| switch(c) { | |||
| case '%': | |||
| goto addchar; | |||
| case 'd': | |||
| if (percentd_found) | |||
| goto fail; | |||
| percentd_found = 1; | |||
| snprintf(buf1, sizeof(buf1), "%0*d", nd, number); | |||
| len = strlen(buf1); | |||
| if ((q - buf + len) > buf_size - 1) | |||
| goto fail; | |||
| memcpy(q, buf1, len); | |||
| q += len; | |||
| break; | |||
| default: | |||
| goto fail; | |||
| } | |||
| } else { | |||
| addchar: | |||
| if ((q - buf) < buf_size - 1) | |||
| *q++ = c; | |||
| } | |||
| } | |||
| if (!percentd_found) | |||
| goto fail; | |||
| *q = '\0'; | |||
| return 0; | |||
| fail: | |||
| *q = '\0'; | |||
| return -1; | |||
| } | |||