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>
48
49 #if HAVE_GLOB
50 /* Locally define as 0 (bitwise-OR no-op) any missing glob options that
51 are non-posix glibc/bsd extensions. */
52 #ifndef GLOB_NOMAGIC
53 #define GLOB_NOMAGIC 0
54 #endif
55 #ifndef GLOB_BRACE
56 #define GLOB_BRACE 0
57 #endif
58
59 #endif /* HAVE_GLOB */
60
62 { 640, 480 },
63 { 720, 480 },
64 { 720, 576 },
65 { 352, 288 },
66 { 352, 240 },
67 { 160, 128 },
68 { 512, 384 },
69 { 640, 352 },
70 { 640, 240 },
71 };
72
74 {
76
81 return 0;
82 }
83 }
84
85 return -1;
86 }
87
88 /**
89 * Get index range of image files matched by path.
90 *
91 * @param pfirst_index pointer to index updated with the first number in the range
92 * @param plast_index pointer to index updated with the last number in the range
93 * @param path path which has to be matched by the image files in the range
94 * @param start_index minimum accepted value for the first index in the range
95 * @return -1 if no image file could be found
96 */
98 const char *path, int start_index, int start_index_range)
99 {
100 int range, last_index, range1, first_index,
ret;
101 AVBPrint filename;
102
104 /* find the first image */
105 for (first_index = start_index; first_index < start_index + start_index_range; first_index++) {
111 break;
112 }
113 if (first_index == start_index + start_index_range) {
116 }
117
118 /* find the last image */
119 last_index = first_index;
120 for (;;) {
122 for (;;) {
124 range1 = 1;
125 else
132 break;
134 /* just in case... */
135 if (
range >= (1 << 30)) {
138 }
139 }
140 /* we are sure than image last_index + range exists */
142 break;
144 }
145 *pfirst_index = first_index;
146 *plast_index = last_index;
151 }
152
154 {
158 else if (
p->filename[strcspn(
p->filename,
"*?{")])
// probably PT_GLOB
160 else if (
p->buf_size == 0)
161 return 0;
163 return 5;
164 else
166 }
167 return 0;
168 }
169
171 {
173 int first_index = 1, last_index = 1;
176
178
180 if (!st) {
182 }
183
184 if (
s->pixel_format &&
189 }
190
193
194 /* find format */
197 else {
200 }
201
202 if (
s->ts_from_file == 2) {
203 #if !HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
204 av_log(s1,
AV_LOG_ERROR,
"POSIX.1-2008 not supported, nanosecond file timestamps unavailable\n");
206 #endif
208 }
else if (
s->ts_from_file)
210 else {
213 }
214
215 if (
s->width &&
s->height) {
218 }
219
224 } else
226 }
229 s->start_number,
s->start_number_range) < 0) {
231 // Fallback to normal mode
233 } else {
235 "Could find no file or sequence with path '%s' and index in the range %d-%d\n",
236 s1->
url,
s->start_number,
s->start_number +
s->start_number_range - 1);
238 }
239 }
240 }
else if (
s->pattern_type ==
PT_GLOB) {
241 #if HAVE_GLOB
242 int gerr;
243 gerr = glob(s1->
url, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC,
NULL, &
s->globstate);
244 if (gerr != 0) {
246 }
247 first_index = 0;
248 last_index =
s->globstate.gl_pathc - 1;
250 #else
252 "Pattern type 'glob' was selected but globbing "
253 "is not supported by this libavformat build\n");
255 #endif
256 }
else if (
s->pattern_type !=
PT_NONE) {
258 "Unknown value '%d' for pattern_type option\n",
s->pattern_type);
260 }
261 s->img_first = first_index;
262 s->img_last = last_index;
263 s->img_number = first_index;
264 /* compute duration */
265 if (!
s->ts_from_file) {
267 st->
duration = last_index - first_index + 1;
268 }
269 }
270
280 } else {
281 const char *str = strrchr(s1->
url,
'.');
285 int probe_buffer_size = 2048;
288 void *fmt_iter =
NULL;
290
291 if (!probe_buffer)
293
294 probe_buffer_size =
avio_read(s1->
pb, probe_buffer, probe_buffer_size);
295 if (probe_buffer_size < 0) {
297 return probe_buffer_size;
298 }
300
301 pd.
buf = probe_buffer;
304
311 continue;
314 break;
315 }
316 }
320 } else
322 }
329 }
333
334 return 0;
335 }
336
337 /**
338 * Add this frame's source path and basename to packet's sidedata
339 * as a dictionary, so it can be used by filters like 'drawtext'.
340 */
343 char *packed_metadata =
NULL;
344 size_t metadata_len;
346
347 av_dict_set(&d,
"lavf.image2dec.source_path", filename, 0);
349
352 if (!packed_metadata)
355 packed_metadata, metadata_len);
359 }
360 return 0;
361 }
362
364 {
366 AVBPrint filename;
368 int size[3] = { 0 },
ret[3] = { 0 };
371
374 /* loop over input */
375 if (
s->loop &&
s->img_number >
s->img_last) {
376 s->img_number =
s->img_first;
377 }
378 if (
s->img_number >
s->img_last)
382 }
else if (
s->use_glob) {
383 #if HAVE_GLOB
384 av_bprintf(&filename,
"%s",
s->globstate.gl_pathv[
s->img_number]);
385 #endif
386 } else {
391 }
392 }
396 }
397 for (
i = 0;
i < 3;
i++) {
399 !strcmp(filename.str, s1->
url) &&
405 break;
407 filename.str);
410 }
412
413 if (!
s->split_planes)
414 break;
415 filename.str[filename.len - 1] =
'U' +
i;
416 }
418
424 int score = 0;
425
430 }
436
440 }
441
444 } else {
450 if (
s->frame_size > 0) {
451 size[0] =
s->frame_size;
454 } else {
456 }
457 }
458
460 if (res < 0) {
462 }
465 if (
s->ts_from_file) {
466 struct stat img_stat;
467 av_assert0(!
s->is_pipe);
// The ts_from_file option is not supported by piped input demuxers
468 if (stat(filename.str, &img_stat)) {
471 }
473 #if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
474 if (
s->ts_from_file == 2)
475 pkt->
pts = 1000000000*
pkt->
pts + img_stat.st_mtim.tv_nsec;
476 #endif
478 }
else if (!
s->is_pipe) {
480 }
481
484
485 /*
486 * export_path_metadata must be explicitly enabled via
487 * command line options for path metadata to be exported
488 * as packet side_data.
489 */
490 if (!
s->is_pipe &&
s->export_path_metadata == 1) {
492 if (res < 0)
494 }
496
498 for (
i = 0;
i < 3;
i++) {
505 }
506 }
507 if (!
s->is_pipe &&
f[
i] != s1->
pb)
511 }
512 }
513
514 if (
ret[0] <= 0 ||
ret[1] < 0 ||
ret[2] < 0) {
517 }
else if (
ret[1] < 0) {
519 }
else if (
ret[2] < 0) {
521 } else {
523 }
525 } else {
530 return 0;
531 }
532
536 for (
i = 0;
i < 3;
i++) {
539 }
540 }
541 return res;
542 }
543
545 {
546 #if HAVE_GLOB
549 globfree(&
s->globstate);
550 }
551 #endif
552 return 0;
553 }
554
556 {
559
563 return -1;
565 return 0;
566 }
567
569 return -1;
572 return 0;
573 }
574
575 #define OFFSET(x) offsetof(VideoDemuxData, x)
576 #define DEC AV_OPT_FLAG_DECODING_PARAM
577 #define COMMON_OPTIONS \
578 { "framerate", "set the video framerate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC }, \
579 { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, \
580 { "video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC }, \
581 { "loop", "force loop over input file sequence", OFFSET(loop), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, DEC }, \
582 { NULL },
583
584 #if CONFIG_IMAGE2_DEMUXER
590 {
"start_number",
"set first number in the sequence",
OFFSET(start_number),
AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX,
DEC },
591 {
"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 },
592 {
"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" },
595 {
"ns",
"nano second precision", 0,
AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 2,
DEC, .unit =
"ts_type" },
596 {
"export_path_metadata",
"enable metadata containing input path information",
OFFSET(export_path_metadata),
AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1,
DEC }, \
597 COMMON_OPTIONS
598 };
599
600 static const AVClass img2_class = {
605 };
610 .p.priv_class = &img2_class,
617 };
618 #endif
619
623 };
629 };
630
631 #if CONFIG_IMAGE2PIPE_DEMUXER
633 .
p.
name =
"image2pipe",
639 };
640 #endif
641
643 {
644 const uint8_t *
b =
p->buf;
645 int ihsize;
646
648 return 0;
649
651 if (ihsize < 12 || ihsize > 255)
652 return 0;
653
656 }
658 }
659
661 {
662 const uint8_t *
b =
p->buf;
663
668 return 0;
669 }
670
672 {
673 const uint8_t *
b =
p->buf;
674
675 if (
AV_RB64(
b) == 0x444453207c000000
679 return 0;
680 }
681
683 {
684 const uint8_t *
b =
p->buf;
687
688 if (
p->buf_size < 0x304+8)
689 return 0;
692 if (
w <= 0 ||
h <= 0)
693 return 0;
694
697 return 0;
698 }
699
701 {
702 const uint8_t *
b =
p->buf;
703
706 return 0;
707 }
708
710 {
711 const uint8_t *
b =
p->buf;
712
713 if (
AV_RB64(
b) == 0x0000000c6a502020 ||
716 return 0;
717 }
718
720 {
721 const uint8_t *
b =
p->buf;
723
726 return 0;
727
729 for (
i = 0;
i <
p->buf_size - 3;
i++) {
732 continue;
736 return 0;
746 return 0;
748 break;
752 return 0;
754 break;
757 return 0;
759 break;
762 got_header = 1;
763 /* fallthrough */
766 got_header = 1;
767 /* fallthrough */
782 case DQT:
/* fallthrough */
785 break;
786 default:
789 return 0;
790 }
791 }
792
798 }
799
801 {
802 const uint8_t *
b =
p->buf;
803
806 return 0;
807 }
808
810 {
811 const uint8_t *
b =
p->buf;
812
813 /* ISOBMFF-based container */
814 /* 0x4a584c20 == "JXL " */
817 /* Raw codestreams all start with 0xff0a */
819 return 0;
820 #if CONFIG_IMAGE_JPEGXL_PIPE_DEMUXER
823 #endif
824 return 0;
825 }
826
828 {
829 const uint8_t *
b =
p->buf;
830
831 if (
p->buf_size < 128
839 return 0;
841 while (++b < p->buf + 128)
844
846 }
847
849 {
850 const uint8_t *
b =
p->buf;
851
852 if (
p->buf_size >= 528
853 && (
AV_RB64(
b + 520) & 0xFFFFFFFFFFFF) == 0x001102ff0c00
857 if ( (
AV_RB64(
b + 8) & 0xFFFFFFFFFFFF) == 0x001102ff0c00
861 return 0;
862 }
863
865 {
866 const uint8_t *
b =
p->buf;
867
870 return 0;
871 }
872
874 {
875 const uint8_t *
b =
p->buf;
876
877 if (
AV_RB64(
b) == 0x89504e470d0a1a0a)
879 return 0;
880 }
881
883 {
884 const uint8_t *
b =
p->buf;
886 uint16_t color_mode;
887
890 } else {
891 return 0;
892 }
893
894 if ((
b[4] == 0) && (
b[5] == 1)) {
/* version 1 is PSD, version 2 is PSB */
896 } else {
897 return 0;
898 }
899
902
904 if ((color_mode <= 9) && (color_mode != 5) && (color_mode != 6))
906
908 }
909
911 {
912 const uint8_t *
b =
p->buf;
913
916 (
b[3] & ~3) == 0 &&
b[3] &&
919 return 0;
920 }
921
923 {
924 const uint8_t *
b =
p->buf;
925
928 return 0;
929 }
930
932 {
933 const uint8_t *
b =
p->buf;
934 const uint8_t *end =
p->buf +
p->buf_size;
938 return 0;
939 if (!memcmp(
b,
"<svg", 4))
941 if (memcmp(
p->buf,
"<?xml", 5) && memcmp(
b,
"<!--", 4))
942 return 0;
946 break;
949 return 0;
950 if (!memcmp(
b,
"<svg", 4))
952 }
953 return 0;
954 }
955
957 {
958 const uint8_t *
b =
p->buf;
959
963 return 0;
964 }
965
967 {
968 const uint8_t *
b =
p->buf;
969
973 return 0;
974 }
975
977 {
978 const uint8_t *
b =
p->buf;
979
980 return b[0] ==
'P' &&
b[1] == magic +
'0';
981 }
982
984 {
985 const uint8_t *
b =
p->buf;
986
989 if (
b[2] ==
'\n' && (
b[3] ==
'#' || (
b[3] >=
'0' &&
b[3] <=
'9')))
991 return 0;
992 }
993
995 {
997 }
998
1000 {
1003 }
1004
1006 {
1009 }
1010
1012 {
1014 }
1015
1017 {
1020 }
1021
1023 {
1026 }
1027
1029 {
1030 const uint8_t *
b =
p->buf;
1031 if (!memcmp(
b,
"PG ML ", 6))
1033 return 0;
1034 }
1035
1037 {
1039 }
1040
1042 {
1044 }
1045
1047 {
1048 if (!memcmp(
p->buf,
"#?RADIANCE\n", 11))
1050 return 0;
1051 }
1052
1054 {
1055 if (!memcmp(
p->buf,
"/* XBM X10 format */", 20))
1057
1058 if (!memcmp(
p->buf,
"#define", 7))
1060 return 0;
1061 }
1062
1064 {
1065 const uint8_t *
b =
p->buf;
1066
1067 if (
AV_RB64(
b) == 0x2f2a2058504d202a && *(
b+8) ==
'/')
1069 return 0;
1070 }
1071
1073 {
1074 const uint8_t *
b =
p->buf;
1075 unsigned width, bpp, bpad, lsize;
1076
1084 ||
AV_RB32(
b + 28) > 1
// byteorder
1089 ||
AV_RB32(
b + 68) > 256)
// colours
1090 return 0;
1091
1097 return 0;
1098
1100 }
1101
1103 {
1104 /* check magick */
1106 return 0;
1107
1108 /* width or height contains zero? */
1110 return 0;
1111
1113 }
1114
1116 {
1117 if (!memcmp(
p->buf,
"PCD_OPA", 7))
1119
1120 if (
p->buf_size < 0x807 || memcmp(
p->buf + 0x800,
"PCD_IPI", 7))
1121 return 0;
1122
1124 }
1125
1127 {
1128 if (memcmp(
p->buf,
"qoif", 4))
1129 return 0;
1130
1132 return 0;
1133
1134 if (
p->buf[12] != 3 &&
p->buf[12] != 4)
1135 return 0;
1136
1138 return 0;
1139
1141 }
1142
1144 {
1145 const uint8_t *
b =
p->buf;
1159 }
1160 return 0;
1161 }
1162
1164 {
1165 const uint8_t *
b =
p->buf;
1170 return 0;
1171 }
1172
1173 #define IMAGEAUTO_DEMUXER_0(imgname, codecid)
1174 #define IMAGEAUTO_DEMUXER_1(imgname, codecid)\
1175 const FFInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\
1176 .p.name = AV_STRINGIFY(imgname) "_pipe",\
1177 .p.long_name = NULL_IF_CONFIG_SMALL("piped " AV_STRINGIFY(imgname) " sequence"),\
1178 .p.priv_class = &imagepipe_class,\
1179 .p.flags = AVFMT_GENERIC_INDEX,\
1180 .priv_data_size = sizeof(VideoDemuxData),\
1181 .read_probe = imgname ## _probe,\
1182 .read_header = ff_img_read_header,\
1183 .read_packet = ff_img_read_packet,\
1184 .raw_codec_id = codecid,\
1185 };
1186
1187 #define IMAGEAUTO_DEMUXER_2(imgname, codecid, enabled) \
1188 IMAGEAUTO_DEMUXER_ ## enabled(imgname, codecid)
1189 #define IMAGEAUTO_DEMUXER_3(imgname, codecid, config) \
1190 IMAGEAUTO_DEMUXER_2(imgname, codecid, config)
1191 #define IMAGEAUTO_DEMUXER_EXT(imgname, codecid, uppercase_name) \
1192 IMAGEAUTO_DEMUXER_3(imgname, AV_CODEC_ID_ ## codecid, \
1193 CONFIG_IMAGE_ ## uppercase_name ## _PIPE_DEMUXER)
1194 #define IMAGEAUTO_DEMUXER(imgname, codecid) \
1195 IMAGEAUTO_DEMUXER_EXT(imgname, codecid, codecid)
1196