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 "config_components.h"
24
25 #define _DEFAULT_SOURCE
27 #include <sys/stat.h>
47
48 #if HAVE_GLOB
49 /* Locally define as 0 (bitwise-OR no-op) any missing glob options that
50 are non-posix glibc/bsd extensions. */
51 #ifndef GLOB_NOMAGIC
52 #define GLOB_NOMAGIC 0
53 #endif
54 #ifndef GLOB_BRACE
55 #define GLOB_BRACE 0
56 #endif
57
58 #endif /* HAVE_GLOB */
59
61 { 640, 480 },
62 { 720, 480 },
63 { 720, 576 },
64 { 352, 288 },
65 { 352, 240 },
66 { 160, 128 },
67 { 512, 384 },
68 { 640, 352 },
69 { 640, 240 },
70 };
71
73 {
75
80 return 0;
81 }
82 }
83
84 return -1;
85 }
86
88 {
89 #if HAVE_GLOB
90 size_t span = 0;
91 const char *p = path;
92
93 while (p = strchr(p, '%')) {
94 if (*(++p) == '%') {
95 ++p;
96 continue;
97 }
98 if (span = strspn(p, "*?[]{}"))
99 break;
100 }
101 /* Did we hit a glob char or get to the end? */
102 return span != 0;
103 #else
104 return 0;
105 #endif
106 }
107
108 /**
109 * Get index range of image files matched by path.
110 *
111 * @param pfirst_index pointer to index updated with the first number in the range
112 * @param plast_index pointer to index updated with the last number in the range
113 * @param path path which has to be matched by the image files in the range
114 * @param start_index minimum accepted value for the first index in the range
115 * @return -1 if no image file could be found
116 */
118 const char *path, int start_index, int start_index_range)
119 {
120 char buf[1024];
121 int range, last_index, range1, first_index;
122
123 /* find the first image */
124 for (first_index = start_index; first_index < start_index + start_index_range; first_index++) {
126 *pfirst_index =
127 *plast_index = 1;
129 return 0;
130 return -1;
131 }
133 break;
134 }
135 if (first_index == start_index + start_index_range)
137
138 /* find the last image */
139 last_index = first_index;
140 for (;;) {
142 for (;;) {
144 range1 = 1;
145 else
148 last_index + range1) < 0)
151 break;
153 /* just in case... */
154 if (
range >= (1 << 30))
156 }
157 /* we are sure than image last_index + range exists */
159 break;
161 }
162 *pfirst_index = first_index;
163 *plast_index = last_index;
164 return 0;
165
167 return -1;
168 }
169
171 {
180 return 0;
182 return 5;
183 else
185 }
186 return 0;
187 }
188
190 {
192 int first_index = 1, last_index = 1;
195
197
199 if (!st) {
201 }
202
203 if (
s->pixel_format &&
208 }
209
213
214 /* find format */
217 else {
220 }
221
222 if (
s->ts_from_file == 2) {
223 #if !HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
224 av_log(
s1,
AV_LOG_ERROR,
"POSIX.1-2008 not supported, nanosecond file timestamps unavailable\n");
226 #endif
228 }
else if (
s->ts_from_file)
230 else {
233 }
234
235 if (
s->width &&
s->height) {
238 }
239
244 } else
246 }
247
251 #if HAVE_GLOB
252 char *p =
s->path, *q, *dup;
253 int gerr;
254 #endif
255
257 "use pattern_type 'glob' instead\n");
258 #if HAVE_GLOB
260 while (*q) {
261 /* Do we have room for the next char and a \ insertion? */
262 if ((p -
s->path) >= (
sizeof(
s->path) - 2))
263 break;
264 if (*q == '%' && strspn(q + 1, "%*?[]{}"))
265 ++q;
266 else if (strspn(q, "\\*?[]{}"))
267 *p++ = '\\';
268 *p++ = *q++;
269 }
270 *p = 0;
272
273 gerr = glob(
s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC,
NULL, &
s->globstate);
274 if (gerr != 0) {
276 }
277 first_index = 0;
278 last_index =
s->globstate.gl_pathc - 1;
279 #endif
280 }
281 }
284 s->start_number,
s->start_number_range) < 0) {
286 "Could find no file with path '%s' and index in the range %d-%d\n",
287 s->path,
s->start_number,
s->start_number +
s->start_number_range - 1);
289 }
290 }
else if (
s->pattern_type ==
PT_GLOB) {
291 #if HAVE_GLOB
292 int gerr;
293 gerr = glob(
s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC,
NULL, &
s->globstate);
294 if (gerr != 0) {
296 }
297 first_index = 0;
298 last_index =
s->globstate.gl_pathc - 1;
300 #else
302 "Pattern type 'glob' was selected but globbing "
303 "is not supported by this libavformat build\n");
305 #endif
308 "Unknown value '%d' for pattern_type option\n",
s->pattern_type);
310 }
311 s->img_first = first_index;
312 s->img_last = last_index;
313 s->img_number = first_index;
314 /* compute duration */
315 if (!
s->ts_from_file) {
317 st->
duration = last_index - first_index + 1;
318 }
319 }
320
321 if (
s1->video_codec_id) {
324 }
else if (
s1->audio_codec_id) {
330 } else {
331 const char *str = strrchr(
s->path,
'.');
335 int probe_buffer_size = 2048;
338 void *fmt_iter =
NULL;
340
341 if (!probe_buffer)
343
344 probe_buffer_size =
avio_read(
s1->pb, probe_buffer, probe_buffer_size);
345 if (probe_buffer_size < 0) {
347 return probe_buffer_size;
348 }
350
351 pd.
buf = probe_buffer;
354
361 continue;
364 break;
365 }
366 }
370 } else
372 }
379 }
383
384 return 0;
385 }
386
387 /**
388 * Add this frame's source path and basename to packet's sidedata
389 * as a dictionary, so it can be used by filters like 'drawtext'.
390 */
393 char *packed_metadata =
NULL;
394 size_t metadata_len;
396
397 av_dict_set(&
d,
"lavf.image2dec.source_path", filename, 0);
399
402 if (!packed_metadata)
405 packed_metadata, metadata_len);
409 }
410 return 0;
411 }
412
414 {
416 char filename_bytes[1024];
417 char *filename = filename_bytes;
419 int size[3] = { 0 },
ret[3] = { 0 };
422
424 /* loop over input */
425 if (
s->loop &&
s->img_number >
s->img_last) {
426 s->img_number =
s->img_first;
427 }
428 if (
s->img_number >
s->img_last)
431 av_strlcpy(filename_bytes,
s->path,
sizeof(filename_bytes));
432 }
else if (
s->use_glob) {
433 #if HAVE_GLOB
434 filename =
s->globstate.gl_pathv[
s->img_number];
435 #endif
436 } else {
439 s->img_number) < 0 &&
s->img_number > 1)
441 }
442 for (
i = 0;
i < 3;
i++) {
444 !strcmp(filename_bytes,
s->path) &&
450 break;
452 filename);
454 }
456
457 if (!
s->split_planes)
458 break;
459 filename[strlen(filename) - 1] =
'U' +
i;
460 }
461
467 int score = 0;
468
477
481 }
482
485 } else {
491 if (
s->frame_size > 0) {
492 size[0] =
s->frame_size;
495 } else {
497 }
498 }
499
501 if (res < 0) {
503 }
506 if (
s->ts_from_file) {
507 struct stat img_stat;
508 av_assert0(!
s->is_pipe);
// The ts_from_file option is not supported by piped input demuxers
509 if (stat(filename, &img_stat)) {
512 }
514 #if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
515 if (
s->ts_from_file == 2)
516 pkt->
pts = 1000000000*
pkt->
pts + img_stat.st_mtim.tv_nsec;
517 #endif
519 }
else if (!
s->is_pipe) {
521 }
522
525
526 /*
527 * export_path_metadata must be explicitly enabled via
528 * command line options for path metadata to be exported
529 * as packet side_data.
530 */
531 if (!
s->is_pipe &&
s->export_path_metadata == 1) {
533 if (res < 0)
535 }
536
538 for (
i = 0;
i < 3;
i++) {
545 }
546 }
547 if (!
s->is_pipe &&
f[
i] !=
s1->pb)
551 }
552 }
553
554 if (
ret[0] <= 0 ||
ret[1] < 0 ||
ret[2] < 0) {
557 }
else if (
ret[1] < 0) {
559 }
else if (
ret[2] < 0) {
561 } else {
563 }
565 } else {
569 return 0;
570 }
571
574 for (
i = 0;
i < 3;
i++) {
577 }
578 }
579 return res;
580 }
581
583 {
584 #if HAVE_GLOB
587 globfree(&
s->globstate);
588 }
589 #endif
590 return 0;
591 }
592
594 {
597
598 if (
s1->ts_from_file) {
601 return -1;
603 return 0;
604 }
605
606 if (timestamp < 0 || !s1->
loop && timestamp >
s1->img_last -
s1->img_first)
607 return -1;
608 s1->img_number = timestamp%(
s1->img_last -
s1->img_first + 1) +
s1->img_first;
610 return 0;
611 }
612
613 #define OFFSET(x) offsetof(VideoDemuxData, x)
614 #define DEC AV_OPT_FLAG_DECODING_PARAM
615 #define COMMON_OPTIONS \
616 { "framerate", "set the video framerate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC }, \
617 { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, \
618 { "video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC }, \
619 { "loop", "force loop over input file sequence", OFFSET(loop), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, DEC }, \
620 { NULL },
621
622 #if CONFIG_IMAGE2_DEMUXER
629 {
"start_number",
"set first number in the sequence",
OFFSET(start_number),
AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX,
DEC },
630 {
"start_number_range",
"set range for looking at the first sequence number",
OFFSET(start_number_range),
AV_OPT_TYPE_INT, {.i64 = 5}, 1, INT_MAX,
DEC },
631 {
"ts_from_file",
"set frame timestamp from file's one",
OFFSET(ts_from_file),
AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2,
DEC, .unit =
"ts_type" },
634 {
"ns",
"nano second precision", 0,
AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 2,
DEC, .unit =
"ts_type" },
635 {
"export_path_metadata",
"enable metadata containing input path information",
OFFSET(export_path_metadata),
AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1,
DEC }, \
636 COMMON_OPTIONS
637 };
638
639 static const AVClass img2_class = {
644 };
649 .p.priv_class = &img2_class,
656 };
657 #endif
658
662 };
668 };
669
670 #if CONFIG_IMAGE2PIPE_DEMUXER
672 .
p.
name =
"image2pipe",
678 };
679 #endif
680
682 {
683 const uint8_t *
b = p->
buf;
684 int ihsize;
685
687 return 0;
688
690 if (ihsize < 12 || ihsize > 255)
691 return 0;
692
695 }
697 }
698
700 {
701 const uint8_t *
b = p->
buf;
702
707 return 0;
708 }
709
711 {
712 const uint8_t *
b = p->
buf;
713
714 if (
AV_RB64(
b) == 0x444453207c000000
718 return 0;
719 }
720
722 {
723 const uint8_t *
b = p->
buf;
726
728 return 0;
731 if (
w <= 0 ||
h <= 0)
732 return 0;
733
736 return 0;
737 }
738
740 {
741 const uint8_t *
b = p->
buf;
742
745 return 0;
746 }
747
749 {
750 const uint8_t *
b = p->
buf;
751
752 if (
AV_RB64(
b) == 0x0000000c6a502020 ||
755 return 0;
756 }
757
759 {
760 const uint8_t *
b = p->
buf;
762
765 return 0;
766
771 continue;
775 return 0;
785 return 0;
787 break;
791 return 0;
793 break;
796 return 0;
798 break;
801 got_header = 1;
802 /* fallthrough */
805 got_header = 1;
806 /* fallthrough */
821 case DQT:
/* fallthrough */
824 break;
825 default:
828 return 0;
829 }
830 }
831
837 }
838
840 {
841 const uint8_t *
b = p->
buf;
842
845 return 0;
846 }
847
849 {
850 const uint8_t *
b = p->
buf;
851
852 /* ISOBMFF-based container */
853 /* 0x4a584c20 == "JXL " */
856 /* Raw codestreams all start with 0xff0a */
858 return 0;
859 #if CONFIG_IMAGE_JPEGXL_PIPE_DEMUXER
862 #endif
863 return 0;
864 }
865
867 {
868 const uint8_t *
b = p->
buf;
869
878 return 0;
880 while (++b < p->buf + 128)
883
885 }
886
888 {
889 const uint8_t *
b = p->
buf;
890
892 && (
AV_RB64(
b + 520) & 0xFFFFFFFFFFFF) == 0x001102ff0c00
896 if ( (
AV_RB64(
b + 8) & 0xFFFFFFFFFFFF) == 0x001102ff0c00
900 return 0;
901 }
902
904 {
905 const uint8_t *
b = p->
buf;
906
909 return 0;
910 }
911
913 {
914 const uint8_t *
b = p->
buf;
915
916 if (
AV_RB64(
b) == 0x89504e470d0a1a0a)
918 return 0;
919 }
920
922 {
923 const uint8_t *
b = p->
buf;
925 uint16_t color_mode;
926
929 } else {
930 return 0;
931 }
932
933 if ((
b[4] == 0) && (
b[5] == 1)) {
/* version 1 is PSD, version 2 is PSB */
935 } else {
936 return 0;
937 }
938
941
943 if ((color_mode <= 9) && (color_mode != 5) && (color_mode != 6))
945
947 }
948
950 {
951 const uint8_t *
b = p->
buf;
952
955 (
b[3] & ~3) == 0 &&
b[3] &&
958 return 0;
959 }
960
962 {
963 const uint8_t *
b = p->
buf;
964
967 return 0;
968 }
969
971 {
972 const uint8_t *
b = p->
buf;
977 return 0;
978 if (!memcmp(
b,
"<svg", 4))
980 if (memcmp(p->
buf,
"<?xml", 5) && memcmp(
b,
"<!--", 4))
981 return 0;
984 if (!inc)
985 break;
988 return 0;
989 if (!memcmp(
b,
"<svg", 4))
991 }
992 return 0;
993 }
994
996 {
997 const uint8_t *
b = p->
buf;
998
1002 return 0;
1003 }
1004
1006 {
1007 const uint8_t *
b = p->
buf;
1008
1012 return 0;
1013 }
1014
1016 {
1017 const uint8_t *
b = p->
buf;
1018
1019 return b[0] ==
'P' &&
b[1] == magic +
'0';
1020 }
1021
1023 {
1024 const uint8_t *
b = p->
buf;
1025
1026 while (
b[2] ==
'\r')
1028 if (
b[2] ==
'\n' && (
b[3] ==
'#' || (
b[3] >=
'0' &&
b[3] <=
'9')))
1030 return 0;
1031 }
1032
1034 {
1036 }
1037
1039 {
1042 }
1043
1045 {
1048 }
1049
1051 {
1053 }
1054
1056 {
1059 }
1060
1062 {
1065 }
1066
1068 {
1069 const uint8_t *
b = p->
buf;
1070 if (!memcmp(
b,
"PG ML ", 6))
1072 return 0;
1073 }
1074
1076 {
1078 }
1079
1081 {
1083 }
1084
1086 {
1087 if (!memcmp(p->
buf,
"#?RADIANCE\n", 11))
1089 return 0;
1090 }
1091
1093 {
1094 if (!memcmp(p->
buf,
"/* XBM X10 format */", 20))
1096
1097 if (!memcmp(p->
buf,
"#define", 7))
1099 return 0;
1100 }
1101
1103 {
1104 const uint8_t *
b = p->
buf;
1105
1106 if (
AV_RB64(
b) == 0x2f2a2058504d202a && *(
b+8) ==
'/')
1108 return 0;
1109 }
1110
1112 {
1113 const uint8_t *
b = p->
buf;
1114 unsigned width, bpp, bpad, lsize;
1115
1123 ||
AV_RB32(
b + 28) > 1
// byteorder
1128 ||
AV_RB32(
b + 68) > 256)
// colours
1129 return 0;
1130
1136 return 0;
1137
1139 }
1140
1142 {
1143 /* check magick */
1145 return 0;
1146
1147 /* width or height contains zero? */
1149 return 0;
1150
1152 }
1153
1155 {
1156 if (!memcmp(p->
buf,
"PCD_OPA", 7))
1158
1159 if (p->
buf_size < 0x807 || memcmp(p->
buf + 0x800,
"PCD_IPI", 7))
1160 return 0;
1161
1163 }
1164
1166 {
1167 if (memcmp(p->
buf,
"qoif", 4))
1168 return 0;
1169
1171 return 0;
1172
1173 if (p->
buf[12] != 3 && p->
buf[12] != 4)
1174 return 0;
1175
1177 return 0;
1178
1180 }
1181
1183 {
1184 const uint8_t *
b = p->
buf;
1198 }
1199 return 0;
1200 }
1201
1203 {
1204 const uint8_t *
b = p->
buf;
1209 return 0;
1210 }
1211
1212 #define IMAGEAUTO_DEMUXER_0(imgname, codecid)
1213 #define IMAGEAUTO_DEMUXER_1(imgname, codecid)\
1214 const FFInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\
1215 .p.name = AV_STRINGIFY(imgname) "_pipe",\
1216 .p.long_name = NULL_IF_CONFIG_SMALL("piped " AV_STRINGIFY(imgname) " sequence"),\
1217 .p.priv_class = &imagepipe_class,\
1218 .p.flags = AVFMT_GENERIC_INDEX,\
1219 .priv_data_size = sizeof(VideoDemuxData),\
1220 .read_probe = imgname ## _probe,\
1221 .read_header = ff_img_read_header,\
1222 .read_packet = ff_img_read_packet,\
1223 .raw_codec_id = codecid,\
1224 };
1225
1226 #define IMAGEAUTO_DEMUXER_2(imgname, codecid, enabled) \
1227 IMAGEAUTO_DEMUXER_ ## enabled(imgname, codecid)
1228 #define IMAGEAUTO_DEMUXER_3(imgname, codecid, config) \
1229 IMAGEAUTO_DEMUXER_2(imgname, codecid, config)
1230 #define IMAGEAUTO_DEMUXER_EXT(imgname, codecid, uppercase_name) \
1231 IMAGEAUTO_DEMUXER_3(imgname, AV_CODEC_ID_ ## codecid, \
1232 CONFIG_IMAGE_ ## uppercase_name ## _PIPE_DEMUXER)
1233 #define IMAGEAUTO_DEMUXER(imgname, codecid) \
1234 IMAGEAUTO_DEMUXER_EXT(imgname, codecid, codecid)
1235