1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Image format 3cabdff1aSopenharmony_ci * Copyright (c) 2000, 2001, 2002 Fabrice Bellard 4cabdff1aSopenharmony_ci * Copyright (c) 2004 Michael Niedermayer 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include "config_components.h" 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci#define _DEFAULT_SOURCE 26cabdff1aSopenharmony_ci#define _BSD_SOURCE 27cabdff1aSopenharmony_ci#include <sys/stat.h> 28cabdff1aSopenharmony_ci#include "libavutil/avstring.h" 29cabdff1aSopenharmony_ci#include "libavutil/log.h" 30cabdff1aSopenharmony_ci#include "libavutil/opt.h" 31cabdff1aSopenharmony_ci#include "libavutil/pixdesc.h" 32cabdff1aSopenharmony_ci#include "libavutil/parseutils.h" 33cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 34cabdff1aSopenharmony_ci#include "libavcodec/gif.h" 35cabdff1aSopenharmony_ci#include "avformat.h" 36cabdff1aSopenharmony_ci#include "avio_internal.h" 37cabdff1aSopenharmony_ci#include "internal.h" 38cabdff1aSopenharmony_ci#include "img2.h" 39cabdff1aSopenharmony_ci#include "jpegxl_probe.h" 40cabdff1aSopenharmony_ci#include "libavcodec/mjpeg.h" 41cabdff1aSopenharmony_ci#include "libavcodec/vbn.h" 42cabdff1aSopenharmony_ci#include "libavcodec/xwd.h" 43cabdff1aSopenharmony_ci#include "subtitles.h" 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci#if HAVE_GLOB 46cabdff1aSopenharmony_ci/* Locally define as 0 (bitwise-OR no-op) any missing glob options that 47cabdff1aSopenharmony_ci are non-posix glibc/bsd extensions. */ 48cabdff1aSopenharmony_ci#ifndef GLOB_NOMAGIC 49cabdff1aSopenharmony_ci#define GLOB_NOMAGIC 0 50cabdff1aSopenharmony_ci#endif 51cabdff1aSopenharmony_ci#ifndef GLOB_BRACE 52cabdff1aSopenharmony_ci#define GLOB_BRACE 0 53cabdff1aSopenharmony_ci#endif 54cabdff1aSopenharmony_ci 55cabdff1aSopenharmony_ci#endif /* HAVE_GLOB */ 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_cistatic const int sizes[][2] = { 58cabdff1aSopenharmony_ci { 640, 480 }, 59cabdff1aSopenharmony_ci { 720, 480 }, 60cabdff1aSopenharmony_ci { 720, 576 }, 61cabdff1aSopenharmony_ci { 352, 288 }, 62cabdff1aSopenharmony_ci { 352, 240 }, 63cabdff1aSopenharmony_ci { 160, 128 }, 64cabdff1aSopenharmony_ci { 512, 384 }, 65cabdff1aSopenharmony_ci { 640, 352 }, 66cabdff1aSopenharmony_ci { 640, 240 }, 67cabdff1aSopenharmony_ci}; 68cabdff1aSopenharmony_ci 69cabdff1aSopenharmony_cistatic int infer_size(int *width_ptr, int *height_ptr, int size) 70cabdff1aSopenharmony_ci{ 71cabdff1aSopenharmony_ci int i; 72cabdff1aSopenharmony_ci 73cabdff1aSopenharmony_ci for (i = 0; i < FF_ARRAY_ELEMS(sizes); i++) { 74cabdff1aSopenharmony_ci if ((sizes[i][0] * sizes[i][1]) == size) { 75cabdff1aSopenharmony_ci *width_ptr = sizes[i][0]; 76cabdff1aSopenharmony_ci *height_ptr = sizes[i][1]; 77cabdff1aSopenharmony_ci return 0; 78cabdff1aSopenharmony_ci } 79cabdff1aSopenharmony_ci } 80cabdff1aSopenharmony_ci 81cabdff1aSopenharmony_ci return -1; 82cabdff1aSopenharmony_ci} 83cabdff1aSopenharmony_ci 84cabdff1aSopenharmony_cistatic int is_glob(const char *path) 85cabdff1aSopenharmony_ci{ 86cabdff1aSopenharmony_ci#if HAVE_GLOB 87cabdff1aSopenharmony_ci size_t span = 0; 88cabdff1aSopenharmony_ci const char *p = path; 89cabdff1aSopenharmony_ci 90cabdff1aSopenharmony_ci while (p = strchr(p, '%')) { 91cabdff1aSopenharmony_ci if (*(++p) == '%') { 92cabdff1aSopenharmony_ci ++p; 93cabdff1aSopenharmony_ci continue; 94cabdff1aSopenharmony_ci } 95cabdff1aSopenharmony_ci if (span = strspn(p, "*?[]{}")) 96cabdff1aSopenharmony_ci break; 97cabdff1aSopenharmony_ci } 98cabdff1aSopenharmony_ci /* Did we hit a glob char or get to the end? */ 99cabdff1aSopenharmony_ci return span != 0; 100cabdff1aSopenharmony_ci#else 101cabdff1aSopenharmony_ci return 0; 102cabdff1aSopenharmony_ci#endif 103cabdff1aSopenharmony_ci} 104cabdff1aSopenharmony_ci 105cabdff1aSopenharmony_ci/** 106cabdff1aSopenharmony_ci * Get index range of image files matched by path. 107cabdff1aSopenharmony_ci * 108cabdff1aSopenharmony_ci * @param pfirst_index pointer to index updated with the first number in the range 109cabdff1aSopenharmony_ci * @param plast_index pointer to index updated with the last number in the range 110cabdff1aSopenharmony_ci * @param path path which has to be matched by the image files in the range 111cabdff1aSopenharmony_ci * @param start_index minimum accepted value for the first index in the range 112cabdff1aSopenharmony_ci * @return -1 if no image file could be found 113cabdff1aSopenharmony_ci */ 114cabdff1aSopenharmony_cistatic int find_image_range(AVIOContext *pb, int *pfirst_index, int *plast_index, 115cabdff1aSopenharmony_ci const char *path, int start_index, int start_index_range) 116cabdff1aSopenharmony_ci{ 117cabdff1aSopenharmony_ci char buf[1024]; 118cabdff1aSopenharmony_ci int range, last_index, range1, first_index; 119cabdff1aSopenharmony_ci 120cabdff1aSopenharmony_ci /* find the first image */ 121cabdff1aSopenharmony_ci for (first_index = start_index; first_index < start_index + start_index_range; first_index++) { 122cabdff1aSopenharmony_ci if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0) { 123cabdff1aSopenharmony_ci *pfirst_index = 124cabdff1aSopenharmony_ci *plast_index = 1; 125cabdff1aSopenharmony_ci if (pb || avio_check(buf, AVIO_FLAG_READ) > 0) 126cabdff1aSopenharmony_ci return 0; 127cabdff1aSopenharmony_ci return -1; 128cabdff1aSopenharmony_ci } 129cabdff1aSopenharmony_ci if (avio_check(buf, AVIO_FLAG_READ) > 0) 130cabdff1aSopenharmony_ci break; 131cabdff1aSopenharmony_ci } 132cabdff1aSopenharmony_ci if (first_index == start_index + start_index_range) 133cabdff1aSopenharmony_ci goto fail; 134cabdff1aSopenharmony_ci 135cabdff1aSopenharmony_ci /* find the last image */ 136cabdff1aSopenharmony_ci last_index = first_index; 137cabdff1aSopenharmony_ci for (;;) { 138cabdff1aSopenharmony_ci range = 0; 139cabdff1aSopenharmony_ci for (;;) { 140cabdff1aSopenharmony_ci if (!range) 141cabdff1aSopenharmony_ci range1 = 1; 142cabdff1aSopenharmony_ci else 143cabdff1aSopenharmony_ci range1 = 2 * range; 144cabdff1aSopenharmony_ci if (av_get_frame_filename(buf, sizeof(buf), path, 145cabdff1aSopenharmony_ci last_index + range1) < 0) 146cabdff1aSopenharmony_ci goto fail; 147cabdff1aSopenharmony_ci if (avio_check(buf, AVIO_FLAG_READ) <= 0) 148cabdff1aSopenharmony_ci break; 149cabdff1aSopenharmony_ci range = range1; 150cabdff1aSopenharmony_ci /* just in case... */ 151cabdff1aSopenharmony_ci if (range >= (1 << 30)) 152cabdff1aSopenharmony_ci goto fail; 153cabdff1aSopenharmony_ci } 154cabdff1aSopenharmony_ci /* we are sure than image last_index + range exists */ 155cabdff1aSopenharmony_ci if (!range) 156cabdff1aSopenharmony_ci break; 157cabdff1aSopenharmony_ci last_index += range; 158cabdff1aSopenharmony_ci } 159cabdff1aSopenharmony_ci *pfirst_index = first_index; 160cabdff1aSopenharmony_ci *plast_index = last_index; 161cabdff1aSopenharmony_ci return 0; 162cabdff1aSopenharmony_ci 163cabdff1aSopenharmony_cifail: 164cabdff1aSopenharmony_ci return -1; 165cabdff1aSopenharmony_ci} 166cabdff1aSopenharmony_ci 167cabdff1aSopenharmony_cistatic int img_read_probe(const AVProbeData *p) 168cabdff1aSopenharmony_ci{ 169cabdff1aSopenharmony_ci if (p->filename && ff_guess_image2_codec(p->filename)) { 170cabdff1aSopenharmony_ci if (av_filename_number_test(p->filename)) 171cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX; 172cabdff1aSopenharmony_ci else if (is_glob(p->filename)) 173cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX; 174cabdff1aSopenharmony_ci else if (p->filename[strcspn(p->filename, "*?{")]) // probably PT_GLOB 175cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 2; // score chosen to be a tad above the image pipes 176cabdff1aSopenharmony_ci else if (p->buf_size == 0) 177cabdff1aSopenharmony_ci return 0; 178cabdff1aSopenharmony_ci else if (av_match_ext(p->filename, "raw") || av_match_ext(p->filename, "gif")) 179cabdff1aSopenharmony_ci return 5; 180cabdff1aSopenharmony_ci else 181cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION; 182cabdff1aSopenharmony_ci } 183cabdff1aSopenharmony_ci return 0; 184cabdff1aSopenharmony_ci} 185cabdff1aSopenharmony_ci 186cabdff1aSopenharmony_ciint ff_img_read_header(AVFormatContext *s1) 187cabdff1aSopenharmony_ci{ 188cabdff1aSopenharmony_ci VideoDemuxData *s = s1->priv_data; 189cabdff1aSopenharmony_ci int first_index = 1, last_index = 1; 190cabdff1aSopenharmony_ci AVStream *st; 191cabdff1aSopenharmony_ci enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; 192cabdff1aSopenharmony_ci 193cabdff1aSopenharmony_ci s1->ctx_flags |= AVFMTCTX_NOHEADER; 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_ci st = avformat_new_stream(s1, NULL); 196cabdff1aSopenharmony_ci if (!st) { 197cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 198cabdff1aSopenharmony_ci } 199cabdff1aSopenharmony_ci 200cabdff1aSopenharmony_ci if (s->pixel_format && 201cabdff1aSopenharmony_ci (pix_fmt = av_get_pix_fmt(s->pixel_format)) == AV_PIX_FMT_NONE) { 202cabdff1aSopenharmony_ci av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", 203cabdff1aSopenharmony_ci s->pixel_format); 204cabdff1aSopenharmony_ci return AVERROR(EINVAL); 205cabdff1aSopenharmony_ci } 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_ci av_strlcpy(s->path, s1->url, sizeof(s->path)); 208cabdff1aSopenharmony_ci s->img_number = 0; 209cabdff1aSopenharmony_ci s->img_count = 0; 210cabdff1aSopenharmony_ci 211cabdff1aSopenharmony_ci /* find format */ 212cabdff1aSopenharmony_ci if (s1->iformat->flags & AVFMT_NOFILE) 213cabdff1aSopenharmony_ci s->is_pipe = 0; 214cabdff1aSopenharmony_ci else { 215cabdff1aSopenharmony_ci s->is_pipe = 1; 216cabdff1aSopenharmony_ci ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL; 217cabdff1aSopenharmony_ci } 218cabdff1aSopenharmony_ci 219cabdff1aSopenharmony_ci if (s->ts_from_file == 2) { 220cabdff1aSopenharmony_ci#if !HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 221cabdff1aSopenharmony_ci av_log(s1, AV_LOG_ERROR, "POSIX.1-2008 not supported, nanosecond file timestamps unavailable\n"); 222cabdff1aSopenharmony_ci return AVERROR(ENOSYS); 223cabdff1aSopenharmony_ci#endif 224cabdff1aSopenharmony_ci avpriv_set_pts_info(st, 64, 1, 1000000000); 225cabdff1aSopenharmony_ci } else if (s->ts_from_file) 226cabdff1aSopenharmony_ci avpriv_set_pts_info(st, 64, 1, 1); 227cabdff1aSopenharmony_ci else { 228cabdff1aSopenharmony_ci avpriv_set_pts_info(st, 64, s->framerate.den, s->framerate.num); 229cabdff1aSopenharmony_ci st->avg_frame_rate = st->r_frame_rate = s->framerate; 230cabdff1aSopenharmony_ci } 231cabdff1aSopenharmony_ci 232cabdff1aSopenharmony_ci if (s->width && s->height) { 233cabdff1aSopenharmony_ci st->codecpar->width = s->width; 234cabdff1aSopenharmony_ci st->codecpar->height = s->height; 235cabdff1aSopenharmony_ci } 236cabdff1aSopenharmony_ci 237cabdff1aSopenharmony_ci if (!s->is_pipe) { 238cabdff1aSopenharmony_ci if (s->pattern_type == PT_DEFAULT) { 239cabdff1aSopenharmony_ci if (s1->pb) { 240cabdff1aSopenharmony_ci s->pattern_type = PT_NONE; 241cabdff1aSopenharmony_ci } else 242cabdff1aSopenharmony_ci s->pattern_type = PT_GLOB_SEQUENCE; 243cabdff1aSopenharmony_ci } 244cabdff1aSopenharmony_ci 245cabdff1aSopenharmony_ci if (s->pattern_type == PT_GLOB_SEQUENCE) { 246cabdff1aSopenharmony_ci s->use_glob = is_glob(s->path); 247cabdff1aSopenharmony_ci if (s->use_glob) { 248cabdff1aSopenharmony_ci#if HAVE_GLOB 249cabdff1aSopenharmony_ci char *p = s->path, *q, *dup; 250cabdff1aSopenharmony_ci int gerr; 251cabdff1aSopenharmony_ci#endif 252cabdff1aSopenharmony_ci 253cabdff1aSopenharmony_ci av_log(s1, AV_LOG_WARNING, "Pattern type 'glob_sequence' is deprecated: " 254cabdff1aSopenharmony_ci "use pattern_type 'glob' instead\n"); 255cabdff1aSopenharmony_ci#if HAVE_GLOB 256cabdff1aSopenharmony_ci dup = q = av_strdup(p); 257cabdff1aSopenharmony_ci while (*q) { 258cabdff1aSopenharmony_ci /* Do we have room for the next char and a \ insertion? */ 259cabdff1aSopenharmony_ci if ((p - s->path) >= (sizeof(s->path) - 2)) 260cabdff1aSopenharmony_ci break; 261cabdff1aSopenharmony_ci if (*q == '%' && strspn(q + 1, "%*?[]{}")) 262cabdff1aSopenharmony_ci ++q; 263cabdff1aSopenharmony_ci else if (strspn(q, "\\*?[]{}")) 264cabdff1aSopenharmony_ci *p++ = '\\'; 265cabdff1aSopenharmony_ci *p++ = *q++; 266cabdff1aSopenharmony_ci } 267cabdff1aSopenharmony_ci *p = 0; 268cabdff1aSopenharmony_ci av_free(dup); 269cabdff1aSopenharmony_ci 270cabdff1aSopenharmony_ci gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate); 271cabdff1aSopenharmony_ci if (gerr != 0) { 272cabdff1aSopenharmony_ci return AVERROR(ENOENT); 273cabdff1aSopenharmony_ci } 274cabdff1aSopenharmony_ci first_index = 0; 275cabdff1aSopenharmony_ci last_index = s->globstate.gl_pathc - 1; 276cabdff1aSopenharmony_ci#endif 277cabdff1aSopenharmony_ci } 278cabdff1aSopenharmony_ci } 279cabdff1aSopenharmony_ci if ((s->pattern_type == PT_GLOB_SEQUENCE && !s->use_glob) || s->pattern_type == PT_SEQUENCE) { 280cabdff1aSopenharmony_ci if (find_image_range(s1->pb, &first_index, &last_index, s->path, 281cabdff1aSopenharmony_ci s->start_number, s->start_number_range) < 0) { 282cabdff1aSopenharmony_ci av_log(s1, AV_LOG_ERROR, 283cabdff1aSopenharmony_ci "Could find no file with path '%s' and index in the range %d-%d\n", 284cabdff1aSopenharmony_ci s->path, s->start_number, s->start_number + s->start_number_range - 1); 285cabdff1aSopenharmony_ci return AVERROR(ENOENT); 286cabdff1aSopenharmony_ci } 287cabdff1aSopenharmony_ci } else if (s->pattern_type == PT_GLOB) { 288cabdff1aSopenharmony_ci#if HAVE_GLOB 289cabdff1aSopenharmony_ci int gerr; 290cabdff1aSopenharmony_ci gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate); 291cabdff1aSopenharmony_ci if (gerr != 0) { 292cabdff1aSopenharmony_ci return AVERROR(ENOENT); 293cabdff1aSopenharmony_ci } 294cabdff1aSopenharmony_ci first_index = 0; 295cabdff1aSopenharmony_ci last_index = s->globstate.gl_pathc - 1; 296cabdff1aSopenharmony_ci s->use_glob = 1; 297cabdff1aSopenharmony_ci#else 298cabdff1aSopenharmony_ci av_log(s1, AV_LOG_ERROR, 299cabdff1aSopenharmony_ci "Pattern type 'glob' was selected but globbing " 300cabdff1aSopenharmony_ci "is not supported by this libavformat build\n"); 301cabdff1aSopenharmony_ci return AVERROR(ENOSYS); 302cabdff1aSopenharmony_ci#endif 303cabdff1aSopenharmony_ci } else if (s->pattern_type != PT_GLOB_SEQUENCE && s->pattern_type != PT_NONE) { 304cabdff1aSopenharmony_ci av_log(s1, AV_LOG_ERROR, 305cabdff1aSopenharmony_ci "Unknown value '%d' for pattern_type option\n", s->pattern_type); 306cabdff1aSopenharmony_ci return AVERROR(EINVAL); 307cabdff1aSopenharmony_ci } 308cabdff1aSopenharmony_ci s->img_first = first_index; 309cabdff1aSopenharmony_ci s->img_last = last_index; 310cabdff1aSopenharmony_ci s->img_number = first_index; 311cabdff1aSopenharmony_ci /* compute duration */ 312cabdff1aSopenharmony_ci if (!s->ts_from_file) { 313cabdff1aSopenharmony_ci st->start_time = 0; 314cabdff1aSopenharmony_ci st->duration = last_index - first_index + 1; 315cabdff1aSopenharmony_ci } 316cabdff1aSopenharmony_ci } 317cabdff1aSopenharmony_ci 318cabdff1aSopenharmony_ci if (s1->video_codec_id) { 319cabdff1aSopenharmony_ci st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; 320cabdff1aSopenharmony_ci st->codecpar->codec_id = s1->video_codec_id; 321cabdff1aSopenharmony_ci } else if (s1->audio_codec_id) { 322cabdff1aSopenharmony_ci st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; 323cabdff1aSopenharmony_ci st->codecpar->codec_id = s1->audio_codec_id; 324cabdff1aSopenharmony_ci } else if (s1->iformat->raw_codec_id) { 325cabdff1aSopenharmony_ci st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; 326cabdff1aSopenharmony_ci st->codecpar->codec_id = s1->iformat->raw_codec_id; 327cabdff1aSopenharmony_ci } else { 328cabdff1aSopenharmony_ci const char *str = strrchr(s->path, '.'); 329cabdff1aSopenharmony_ci s->split_planes = str && !av_strcasecmp(str + 1, "y"); 330cabdff1aSopenharmony_ci st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; 331cabdff1aSopenharmony_ci if (s1->pb) { 332cabdff1aSopenharmony_ci int probe_buffer_size = 2048; 333cabdff1aSopenharmony_ci uint8_t *probe_buffer = av_realloc(NULL, probe_buffer_size + AVPROBE_PADDING_SIZE); 334cabdff1aSopenharmony_ci const AVInputFormat *fmt = NULL; 335cabdff1aSopenharmony_ci void *fmt_iter = NULL; 336cabdff1aSopenharmony_ci AVProbeData pd = { 0 }; 337cabdff1aSopenharmony_ci 338cabdff1aSopenharmony_ci if (!probe_buffer) 339cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 340cabdff1aSopenharmony_ci 341cabdff1aSopenharmony_ci probe_buffer_size = avio_read(s1->pb, probe_buffer, probe_buffer_size); 342cabdff1aSopenharmony_ci if (probe_buffer_size < 0) { 343cabdff1aSopenharmony_ci av_free(probe_buffer); 344cabdff1aSopenharmony_ci return probe_buffer_size; 345cabdff1aSopenharmony_ci } 346cabdff1aSopenharmony_ci memset(probe_buffer + probe_buffer_size, 0, AVPROBE_PADDING_SIZE); 347cabdff1aSopenharmony_ci 348cabdff1aSopenharmony_ci pd.buf = probe_buffer; 349cabdff1aSopenharmony_ci pd.buf_size = probe_buffer_size; 350cabdff1aSopenharmony_ci pd.filename = s1->url; 351cabdff1aSopenharmony_ci 352cabdff1aSopenharmony_ci while ((fmt = av_demuxer_iterate(&fmt_iter))) { 353cabdff1aSopenharmony_ci if (fmt->read_header != ff_img_read_header || 354cabdff1aSopenharmony_ci !fmt->read_probe || 355cabdff1aSopenharmony_ci (fmt->flags & AVFMT_NOFILE) || 356cabdff1aSopenharmony_ci !fmt->raw_codec_id) 357cabdff1aSopenharmony_ci continue; 358cabdff1aSopenharmony_ci if (fmt->read_probe(&pd) > 0) { 359cabdff1aSopenharmony_ci st->codecpar->codec_id = fmt->raw_codec_id; 360cabdff1aSopenharmony_ci break; 361cabdff1aSopenharmony_ci } 362cabdff1aSopenharmony_ci } 363cabdff1aSopenharmony_ci if (s1->flags & AVFMT_FLAG_CUSTOM_IO) { 364cabdff1aSopenharmony_ci avio_seek(s1->pb, 0, SEEK_SET); 365cabdff1aSopenharmony_ci av_freep(&probe_buffer); 366cabdff1aSopenharmony_ci } else 367cabdff1aSopenharmony_ci ffio_rewind_with_probe_data(s1->pb, &probe_buffer, probe_buffer_size); 368cabdff1aSopenharmony_ci } 369cabdff1aSopenharmony_ci if (st->codecpar->codec_id == AV_CODEC_ID_NONE) 370cabdff1aSopenharmony_ci st->codecpar->codec_id = ff_guess_image2_codec(s->path); 371cabdff1aSopenharmony_ci if (st->codecpar->codec_id == AV_CODEC_ID_LJPEG) 372cabdff1aSopenharmony_ci st->codecpar->codec_id = AV_CODEC_ID_MJPEG; 373cabdff1aSopenharmony_ci if (st->codecpar->codec_id == AV_CODEC_ID_ALIAS_PIX) // we cannot distingiush this from BRENDER_PIX 374cabdff1aSopenharmony_ci st->codecpar->codec_id = AV_CODEC_ID_NONE; 375cabdff1aSopenharmony_ci } 376cabdff1aSopenharmony_ci if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && 377cabdff1aSopenharmony_ci pix_fmt != AV_PIX_FMT_NONE) 378cabdff1aSopenharmony_ci st->codecpar->format = pix_fmt; 379cabdff1aSopenharmony_ci 380cabdff1aSopenharmony_ci return 0; 381cabdff1aSopenharmony_ci} 382cabdff1aSopenharmony_ci 383cabdff1aSopenharmony_ci/** 384cabdff1aSopenharmony_ci * Add this frame's source path and basename to packet's sidedata 385cabdff1aSopenharmony_ci * as a dictionary, so it can be used by filters like 'drawtext'. 386cabdff1aSopenharmony_ci */ 387cabdff1aSopenharmony_cistatic int add_filename_as_pkt_side_data(char *filename, AVPacket *pkt) { 388cabdff1aSopenharmony_ci AVDictionary *d = NULL; 389cabdff1aSopenharmony_ci char *packed_metadata = NULL; 390cabdff1aSopenharmony_ci size_t metadata_len; 391cabdff1aSopenharmony_ci int ret; 392cabdff1aSopenharmony_ci 393cabdff1aSopenharmony_ci av_dict_set(&d, "lavf.image2dec.source_path", filename, 0); 394cabdff1aSopenharmony_ci av_dict_set(&d, "lavf.image2dec.source_basename", av_basename(filename), 0); 395cabdff1aSopenharmony_ci 396cabdff1aSopenharmony_ci packed_metadata = av_packet_pack_dictionary(d, &metadata_len); 397cabdff1aSopenharmony_ci av_dict_free(&d); 398cabdff1aSopenharmony_ci if (!packed_metadata) 399cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 400cabdff1aSopenharmony_ci ret = av_packet_add_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, 401cabdff1aSopenharmony_ci packed_metadata, metadata_len); 402cabdff1aSopenharmony_ci if (ret < 0) { 403cabdff1aSopenharmony_ci av_freep(&packed_metadata); 404cabdff1aSopenharmony_ci return ret; 405cabdff1aSopenharmony_ci } 406cabdff1aSopenharmony_ci return 0; 407cabdff1aSopenharmony_ci} 408cabdff1aSopenharmony_ci 409cabdff1aSopenharmony_ciint ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) 410cabdff1aSopenharmony_ci{ 411cabdff1aSopenharmony_ci VideoDemuxData *s = s1->priv_data; 412cabdff1aSopenharmony_ci char filename_bytes[1024]; 413cabdff1aSopenharmony_ci char *filename = filename_bytes; 414cabdff1aSopenharmony_ci int i, res; 415cabdff1aSopenharmony_ci int size[3] = { 0 }, ret[3] = { 0 }; 416cabdff1aSopenharmony_ci AVIOContext *f[3] = { NULL }; 417cabdff1aSopenharmony_ci AVCodecParameters *par = s1->streams[0]->codecpar; 418cabdff1aSopenharmony_ci 419cabdff1aSopenharmony_ci if (!s->is_pipe) { 420cabdff1aSopenharmony_ci /* loop over input */ 421cabdff1aSopenharmony_ci if (s->loop && s->img_number > s->img_last) { 422cabdff1aSopenharmony_ci s->img_number = s->img_first; 423cabdff1aSopenharmony_ci } 424cabdff1aSopenharmony_ci if (s->img_number > s->img_last) 425cabdff1aSopenharmony_ci return AVERROR_EOF; 426cabdff1aSopenharmony_ci if (s->pattern_type == PT_NONE) { 427cabdff1aSopenharmony_ci av_strlcpy(filename_bytes, s->path, sizeof(filename_bytes)); 428cabdff1aSopenharmony_ci } else if (s->use_glob) { 429cabdff1aSopenharmony_ci#if HAVE_GLOB 430cabdff1aSopenharmony_ci filename = s->globstate.gl_pathv[s->img_number]; 431cabdff1aSopenharmony_ci#endif 432cabdff1aSopenharmony_ci } else { 433cabdff1aSopenharmony_ci if (av_get_frame_filename(filename_bytes, sizeof(filename_bytes), 434cabdff1aSopenharmony_ci s->path, 435cabdff1aSopenharmony_ci s->img_number) < 0 && s->img_number > 1) 436cabdff1aSopenharmony_ci return AVERROR(EIO); 437cabdff1aSopenharmony_ci } 438cabdff1aSopenharmony_ci for (i = 0; i < 3; i++) { 439cabdff1aSopenharmony_ci if (s1->pb && 440cabdff1aSopenharmony_ci !strcmp(filename_bytes, s->path) && 441cabdff1aSopenharmony_ci !s->loop && 442cabdff1aSopenharmony_ci !s->split_planes) { 443cabdff1aSopenharmony_ci f[i] = s1->pb; 444cabdff1aSopenharmony_ci } else if (s1->io_open(s1, &f[i], filename, AVIO_FLAG_READ, NULL) < 0) { 445cabdff1aSopenharmony_ci if (i >= 1) 446cabdff1aSopenharmony_ci break; 447cabdff1aSopenharmony_ci av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n", 448cabdff1aSopenharmony_ci filename); 449cabdff1aSopenharmony_ci return AVERROR(EIO); 450cabdff1aSopenharmony_ci } 451cabdff1aSopenharmony_ci size[i] = avio_size(f[i]); 452cabdff1aSopenharmony_ci 453cabdff1aSopenharmony_ci if (!s->split_planes) 454cabdff1aSopenharmony_ci break; 455cabdff1aSopenharmony_ci filename[strlen(filename) - 1] = 'U' + i; 456cabdff1aSopenharmony_ci } 457cabdff1aSopenharmony_ci 458cabdff1aSopenharmony_ci if (par->codec_id == AV_CODEC_ID_NONE) { 459cabdff1aSopenharmony_ci AVProbeData pd = { 0 }; 460cabdff1aSopenharmony_ci const AVInputFormat *ifmt; 461cabdff1aSopenharmony_ci uint8_t header[PROBE_BUF_MIN + AVPROBE_PADDING_SIZE]; 462cabdff1aSopenharmony_ci int ret; 463cabdff1aSopenharmony_ci int score = 0; 464cabdff1aSopenharmony_ci 465cabdff1aSopenharmony_ci ret = avio_read(f[0], header, PROBE_BUF_MIN); 466cabdff1aSopenharmony_ci if (ret < 0) 467cabdff1aSopenharmony_ci return ret; 468cabdff1aSopenharmony_ci memset(header + ret, 0, sizeof(header) - ret); 469cabdff1aSopenharmony_ci avio_skip(f[0], -ret); 470cabdff1aSopenharmony_ci pd.buf = header; 471cabdff1aSopenharmony_ci pd.buf_size = ret; 472cabdff1aSopenharmony_ci pd.filename = filename; 473cabdff1aSopenharmony_ci 474cabdff1aSopenharmony_ci ifmt = av_probe_input_format3(&pd, 1, &score); 475cabdff1aSopenharmony_ci if (ifmt && ifmt->read_packet == ff_img_read_packet && ifmt->raw_codec_id) 476cabdff1aSopenharmony_ci par->codec_id = ifmt->raw_codec_id; 477cabdff1aSopenharmony_ci } 478cabdff1aSopenharmony_ci 479cabdff1aSopenharmony_ci if (par->codec_id == AV_CODEC_ID_RAWVIDEO && !par->width) 480cabdff1aSopenharmony_ci infer_size(&par->width, &par->height, size[0]); 481cabdff1aSopenharmony_ci } else { 482cabdff1aSopenharmony_ci f[0] = s1->pb; 483cabdff1aSopenharmony_ci if (avio_feof(f[0]) && s->loop && s->is_pipe) 484cabdff1aSopenharmony_ci avio_seek(f[0], 0, SEEK_SET); 485cabdff1aSopenharmony_ci if (avio_feof(f[0])) 486cabdff1aSopenharmony_ci return AVERROR_EOF; 487cabdff1aSopenharmony_ci if (s->frame_size > 0) { 488cabdff1aSopenharmony_ci size[0] = s->frame_size; 489cabdff1aSopenharmony_ci } else if (!ffstream(s1->streams[0])->parser) { 490cabdff1aSopenharmony_ci size[0] = avio_size(s1->pb); 491cabdff1aSopenharmony_ci } else { 492cabdff1aSopenharmony_ci size[0] = 4096; 493cabdff1aSopenharmony_ci } 494cabdff1aSopenharmony_ci } 495cabdff1aSopenharmony_ci 496cabdff1aSopenharmony_ci res = av_new_packet(pkt, size[0] + size[1] + size[2]); 497cabdff1aSopenharmony_ci if (res < 0) { 498cabdff1aSopenharmony_ci goto fail; 499cabdff1aSopenharmony_ci } 500cabdff1aSopenharmony_ci pkt->stream_index = 0; 501cabdff1aSopenharmony_ci pkt->flags |= AV_PKT_FLAG_KEY; 502cabdff1aSopenharmony_ci if (s->ts_from_file) { 503cabdff1aSopenharmony_ci struct stat img_stat; 504cabdff1aSopenharmony_ci if (stat(filename, &img_stat)) { 505cabdff1aSopenharmony_ci res = AVERROR(EIO); 506cabdff1aSopenharmony_ci goto fail; 507cabdff1aSopenharmony_ci } 508cabdff1aSopenharmony_ci pkt->pts = (int64_t)img_stat.st_mtime; 509cabdff1aSopenharmony_ci#if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 510cabdff1aSopenharmony_ci if (s->ts_from_file == 2) 511cabdff1aSopenharmony_ci pkt->pts = 1000000000*pkt->pts + img_stat.st_mtim.tv_nsec; 512cabdff1aSopenharmony_ci#endif 513cabdff1aSopenharmony_ci av_add_index_entry(s1->streams[0], s->img_number, pkt->pts, 0, 0, AVINDEX_KEYFRAME); 514cabdff1aSopenharmony_ci } else if (!s->is_pipe) { 515cabdff1aSopenharmony_ci pkt->pts = s->pts; 516cabdff1aSopenharmony_ci } 517cabdff1aSopenharmony_ci 518cabdff1aSopenharmony_ci if (s->is_pipe) 519cabdff1aSopenharmony_ci pkt->pos = avio_tell(f[0]); 520cabdff1aSopenharmony_ci 521cabdff1aSopenharmony_ci /* 522cabdff1aSopenharmony_ci * export_path_metadata must be explicitly enabled via 523cabdff1aSopenharmony_ci * command line options for path metadata to be exported 524cabdff1aSopenharmony_ci * as packet side_data. 525cabdff1aSopenharmony_ci */ 526cabdff1aSopenharmony_ci if (!s->is_pipe && s->export_path_metadata == 1) { 527cabdff1aSopenharmony_ci res = add_filename_as_pkt_side_data(filename, pkt); 528cabdff1aSopenharmony_ci if (res < 0) 529cabdff1aSopenharmony_ci goto fail; 530cabdff1aSopenharmony_ci } 531cabdff1aSopenharmony_ci 532cabdff1aSopenharmony_ci pkt->size = 0; 533cabdff1aSopenharmony_ci for (i = 0; i < 3; i++) { 534cabdff1aSopenharmony_ci if (f[i]) { 535cabdff1aSopenharmony_ci ret[i] = avio_read(f[i], pkt->data + pkt->size, size[i]); 536cabdff1aSopenharmony_ci if (s->loop && s->is_pipe && ret[i] == AVERROR_EOF) { 537cabdff1aSopenharmony_ci if (avio_seek(f[i], 0, SEEK_SET) >= 0) { 538cabdff1aSopenharmony_ci pkt->pos = 0; 539cabdff1aSopenharmony_ci ret[i] = avio_read(f[i], pkt->data + pkt->size, size[i]); 540cabdff1aSopenharmony_ci } 541cabdff1aSopenharmony_ci } 542cabdff1aSopenharmony_ci if (!s->is_pipe && f[i] != s1->pb) 543cabdff1aSopenharmony_ci ff_format_io_close(s1, &f[i]); 544cabdff1aSopenharmony_ci if (ret[i] > 0) 545cabdff1aSopenharmony_ci pkt->size += ret[i]; 546cabdff1aSopenharmony_ci } 547cabdff1aSopenharmony_ci } 548cabdff1aSopenharmony_ci 549cabdff1aSopenharmony_ci if (ret[0] <= 0 || ret[1] < 0 || ret[2] < 0) { 550cabdff1aSopenharmony_ci if (ret[0] < 0) { 551cabdff1aSopenharmony_ci res = ret[0]; 552cabdff1aSopenharmony_ci } else if (ret[1] < 0) { 553cabdff1aSopenharmony_ci res = ret[1]; 554cabdff1aSopenharmony_ci } else if (ret[2] < 0) { 555cabdff1aSopenharmony_ci res = ret[2]; 556cabdff1aSopenharmony_ci } else { 557cabdff1aSopenharmony_ci res = AVERROR_EOF; 558cabdff1aSopenharmony_ci } 559cabdff1aSopenharmony_ci goto fail; 560cabdff1aSopenharmony_ci } else { 561cabdff1aSopenharmony_ci memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE); 562cabdff1aSopenharmony_ci s->img_count++; 563cabdff1aSopenharmony_ci s->img_number++; 564cabdff1aSopenharmony_ci s->pts++; 565cabdff1aSopenharmony_ci return 0; 566cabdff1aSopenharmony_ci } 567cabdff1aSopenharmony_ci 568cabdff1aSopenharmony_cifail: 569cabdff1aSopenharmony_ci if (!s->is_pipe) { 570cabdff1aSopenharmony_ci for (i = 0; i < 3; i++) { 571cabdff1aSopenharmony_ci if (f[i] != s1->pb) 572cabdff1aSopenharmony_ci ff_format_io_close(s1, &f[i]); 573cabdff1aSopenharmony_ci } 574cabdff1aSopenharmony_ci } 575cabdff1aSopenharmony_ci return res; 576cabdff1aSopenharmony_ci} 577cabdff1aSopenharmony_ci 578cabdff1aSopenharmony_cistatic int img_read_close(struct AVFormatContext* s1) 579cabdff1aSopenharmony_ci{ 580cabdff1aSopenharmony_ci#if HAVE_GLOB 581cabdff1aSopenharmony_ci VideoDemuxData *s = s1->priv_data; 582cabdff1aSopenharmony_ci if (s->use_glob) { 583cabdff1aSopenharmony_ci globfree(&s->globstate); 584cabdff1aSopenharmony_ci } 585cabdff1aSopenharmony_ci#endif 586cabdff1aSopenharmony_ci return 0; 587cabdff1aSopenharmony_ci} 588cabdff1aSopenharmony_ci 589cabdff1aSopenharmony_cistatic int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) 590cabdff1aSopenharmony_ci{ 591cabdff1aSopenharmony_ci VideoDemuxData *s1 = s->priv_data; 592cabdff1aSopenharmony_ci AVStream *st = s->streams[0]; 593cabdff1aSopenharmony_ci 594cabdff1aSopenharmony_ci if (s1->ts_from_file) { 595cabdff1aSopenharmony_ci int index = av_index_search_timestamp(st, timestamp, flags); 596cabdff1aSopenharmony_ci if(index < 0) 597cabdff1aSopenharmony_ci return -1; 598cabdff1aSopenharmony_ci s1->img_number = ffstream(st)->index_entries[index].pos; 599cabdff1aSopenharmony_ci return 0; 600cabdff1aSopenharmony_ci } 601cabdff1aSopenharmony_ci 602cabdff1aSopenharmony_ci if (timestamp < 0 || !s1->loop && timestamp > s1->img_last - s1->img_first) 603cabdff1aSopenharmony_ci return -1; 604cabdff1aSopenharmony_ci s1->img_number = timestamp%(s1->img_last - s1->img_first + 1) + s1->img_first; 605cabdff1aSopenharmony_ci s1->pts = timestamp; 606cabdff1aSopenharmony_ci return 0; 607cabdff1aSopenharmony_ci} 608cabdff1aSopenharmony_ci 609cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(VideoDemuxData, x) 610cabdff1aSopenharmony_ci#define DEC AV_OPT_FLAG_DECODING_PARAM 611cabdff1aSopenharmony_ci#define COMMON_OPTIONS \ 612cabdff1aSopenharmony_ci { "framerate", "set the video framerate", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, DEC }, \ 613cabdff1aSopenharmony_ci { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, \ 614cabdff1aSopenharmony_ci { "video_size", "set video size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC }, \ 615cabdff1aSopenharmony_ci { "loop", "force loop over input file sequence", OFFSET(loop), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, DEC }, \ 616cabdff1aSopenharmony_ci { NULL }, 617cabdff1aSopenharmony_ci 618cabdff1aSopenharmony_ci#if CONFIG_IMAGE2_DEMUXER 619cabdff1aSopenharmony_ciconst AVOption ff_img_options[] = { 620cabdff1aSopenharmony_ci { "pattern_type", "set pattern type", OFFSET(pattern_type), AV_OPT_TYPE_INT, {.i64=PT_DEFAULT}, 0, INT_MAX, DEC, "pattern_type"}, 621cabdff1aSopenharmony_ci { "glob_sequence","select glob/sequence pattern type", 0, AV_OPT_TYPE_CONST, {.i64=PT_GLOB_SEQUENCE}, INT_MIN, INT_MAX, DEC, "pattern_type" }, 622cabdff1aSopenharmony_ci { "glob", "select glob pattern type", 0, AV_OPT_TYPE_CONST, {.i64=PT_GLOB }, INT_MIN, INT_MAX, DEC, "pattern_type" }, 623cabdff1aSopenharmony_ci { "sequence", "select sequence pattern type", 0, AV_OPT_TYPE_CONST, {.i64=PT_SEQUENCE }, INT_MIN, INT_MAX, DEC, "pattern_type" }, 624cabdff1aSopenharmony_ci { "none", "disable pattern matching", 0, AV_OPT_TYPE_CONST, {.i64=PT_NONE }, INT_MIN, INT_MAX, DEC, "pattern_type" }, 625cabdff1aSopenharmony_ci { "start_number", "set first number in the sequence", OFFSET(start_number), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, DEC }, 626cabdff1aSopenharmony_ci { "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 }, 627cabdff1aSopenharmony_ci { "ts_from_file", "set frame timestamp from file's one", OFFSET(ts_from_file), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 2, DEC, "ts_type" }, 628cabdff1aSopenharmony_ci { "none", "none", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, 0, 2, DEC, "ts_type" }, 629cabdff1aSopenharmony_ci { "sec", "second precision", 0, AV_OPT_TYPE_CONST, {.i64 = 1 }, 0, 2, DEC, "ts_type" }, 630cabdff1aSopenharmony_ci { "ns", "nano second precision", 0, AV_OPT_TYPE_CONST, {.i64 = 2 }, 0, 2, DEC, "ts_type" }, 631cabdff1aSopenharmony_ci { "export_path_metadata", "enable metadata containing input path information", OFFSET(export_path_metadata), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, DEC }, \ 632cabdff1aSopenharmony_ci COMMON_OPTIONS 633cabdff1aSopenharmony_ci}; 634cabdff1aSopenharmony_ci 635cabdff1aSopenharmony_cistatic const AVClass img2_class = { 636cabdff1aSopenharmony_ci .class_name = "image2 demuxer", 637cabdff1aSopenharmony_ci .item_name = av_default_item_name, 638cabdff1aSopenharmony_ci .option = ff_img_options, 639cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 640cabdff1aSopenharmony_ci}; 641cabdff1aSopenharmony_ciconst AVInputFormat ff_image2_demuxer = { 642cabdff1aSopenharmony_ci .name = "image2", 643cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("image2 sequence"), 644cabdff1aSopenharmony_ci .priv_data_size = sizeof(VideoDemuxData), 645cabdff1aSopenharmony_ci .read_probe = img_read_probe, 646cabdff1aSopenharmony_ci .read_header = ff_img_read_header, 647cabdff1aSopenharmony_ci .read_packet = ff_img_read_packet, 648cabdff1aSopenharmony_ci .read_close = img_read_close, 649cabdff1aSopenharmony_ci .read_seek = img_read_seek, 650cabdff1aSopenharmony_ci .flags = AVFMT_NOFILE, 651cabdff1aSopenharmony_ci .priv_class = &img2_class, 652cabdff1aSopenharmony_ci}; 653cabdff1aSopenharmony_ci#endif 654cabdff1aSopenharmony_ci 655cabdff1aSopenharmony_cistatic const AVOption img2pipe_options[] = { 656cabdff1aSopenharmony_ci { "frame_size", "force frame size in bytes", OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, DEC }, 657cabdff1aSopenharmony_ci COMMON_OPTIONS 658cabdff1aSopenharmony_ci}; 659cabdff1aSopenharmony_cistatic const AVClass imagepipe_class = { 660cabdff1aSopenharmony_ci .class_name = "imagepipe demuxer", 661cabdff1aSopenharmony_ci .item_name = av_default_item_name, 662cabdff1aSopenharmony_ci .option = img2pipe_options, 663cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 664cabdff1aSopenharmony_ci}; 665cabdff1aSopenharmony_ci 666cabdff1aSopenharmony_ci#if CONFIG_IMAGE2PIPE_DEMUXER 667cabdff1aSopenharmony_ciconst AVInputFormat ff_image2pipe_demuxer = { 668cabdff1aSopenharmony_ci .name = "image2pipe", 669cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("piped image2 sequence"), 670cabdff1aSopenharmony_ci .priv_data_size = sizeof(VideoDemuxData), 671cabdff1aSopenharmony_ci .read_header = ff_img_read_header, 672cabdff1aSopenharmony_ci .read_packet = ff_img_read_packet, 673cabdff1aSopenharmony_ci .priv_class = &imagepipe_class, 674cabdff1aSopenharmony_ci}; 675cabdff1aSopenharmony_ci#endif 676cabdff1aSopenharmony_ci 677cabdff1aSopenharmony_cistatic int bmp_probe(const AVProbeData *p) 678cabdff1aSopenharmony_ci{ 679cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 680cabdff1aSopenharmony_ci int ihsize; 681cabdff1aSopenharmony_ci 682cabdff1aSopenharmony_ci if (AV_RB16(b) != 0x424d) 683cabdff1aSopenharmony_ci return 0; 684cabdff1aSopenharmony_ci 685cabdff1aSopenharmony_ci ihsize = AV_RL32(b+14); 686cabdff1aSopenharmony_ci if (ihsize < 12 || ihsize > 255) 687cabdff1aSopenharmony_ci return 0; 688cabdff1aSopenharmony_ci 689cabdff1aSopenharmony_ci if (!AV_RN32(b + 6)) { 690cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 691cabdff1aSopenharmony_ci } 692cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION / 4; 693cabdff1aSopenharmony_ci} 694cabdff1aSopenharmony_ci 695cabdff1aSopenharmony_cistatic int cri_probe(const AVProbeData *p) 696cabdff1aSopenharmony_ci{ 697cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 698cabdff1aSopenharmony_ci 699cabdff1aSopenharmony_ci if ( AV_RL32(b) == 1 700cabdff1aSopenharmony_ci && AV_RL32(b + 4) == 4 701cabdff1aSopenharmony_ci && AV_RN32(b + 8) == AV_RN32("DVCC")) 702cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX - 1; 703cabdff1aSopenharmony_ci return 0; 704cabdff1aSopenharmony_ci} 705cabdff1aSopenharmony_ci 706cabdff1aSopenharmony_cistatic int dds_probe(const AVProbeData *p) 707cabdff1aSopenharmony_ci{ 708cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 709cabdff1aSopenharmony_ci 710cabdff1aSopenharmony_ci if ( AV_RB64(b) == 0x444453207c000000 711cabdff1aSopenharmony_ci && AV_RL32(b + 8) 712cabdff1aSopenharmony_ci && AV_RL32(b + 12)) 713cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX - 1; 714cabdff1aSopenharmony_ci return 0; 715cabdff1aSopenharmony_ci} 716cabdff1aSopenharmony_ci 717cabdff1aSopenharmony_cistatic int dpx_probe(const AVProbeData *p) 718cabdff1aSopenharmony_ci{ 719cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 720cabdff1aSopenharmony_ci int w, h; 721cabdff1aSopenharmony_ci int is_big = (AV_RN32(b) == AV_RN32("SDPX")); 722cabdff1aSopenharmony_ci 723cabdff1aSopenharmony_ci if (p->buf_size < 0x304+8) 724cabdff1aSopenharmony_ci return 0; 725cabdff1aSopenharmony_ci w = is_big ? AV_RB32(p->buf + 0x304) : AV_RL32(p->buf + 0x304); 726cabdff1aSopenharmony_ci h = is_big ? AV_RB32(p->buf + 0x308) : AV_RL32(p->buf + 0x308); 727cabdff1aSopenharmony_ci if (w <= 0 || h <= 0) 728cabdff1aSopenharmony_ci return 0; 729cabdff1aSopenharmony_ci 730cabdff1aSopenharmony_ci if (is_big || AV_RN32(b) == AV_RN32("XPDS")) 731cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 732cabdff1aSopenharmony_ci return 0; 733cabdff1aSopenharmony_ci} 734cabdff1aSopenharmony_ci 735cabdff1aSopenharmony_cistatic int exr_probe(const AVProbeData *p) 736cabdff1aSopenharmony_ci{ 737cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 738cabdff1aSopenharmony_ci 739cabdff1aSopenharmony_ci if (AV_RL32(b) == 20000630) 740cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 741cabdff1aSopenharmony_ci return 0; 742cabdff1aSopenharmony_ci} 743cabdff1aSopenharmony_ci 744cabdff1aSopenharmony_cistatic int j2k_probe(const AVProbeData *p) 745cabdff1aSopenharmony_ci{ 746cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 747cabdff1aSopenharmony_ci 748cabdff1aSopenharmony_ci if (AV_RB64(b) == 0x0000000c6a502020 || 749cabdff1aSopenharmony_ci AV_RB32(b) == 0xff4fff51) 750cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 751cabdff1aSopenharmony_ci return 0; 752cabdff1aSopenharmony_ci} 753cabdff1aSopenharmony_ci 754cabdff1aSopenharmony_cistatic int jpeg_probe(const AVProbeData *p) 755cabdff1aSopenharmony_ci{ 756cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 757cabdff1aSopenharmony_ci int i, state = SOI, got_header = 0; 758cabdff1aSopenharmony_ci 759cabdff1aSopenharmony_ci if (AV_RB16(b) != 0xFFD8 || 760cabdff1aSopenharmony_ci AV_RB32(b) == 0xFFD8FFF7) 761cabdff1aSopenharmony_ci return 0; 762cabdff1aSopenharmony_ci 763cabdff1aSopenharmony_ci b += 2; 764cabdff1aSopenharmony_ci for (i = 0; i < p->buf_size - 3; i++) { 765cabdff1aSopenharmony_ci int c; 766cabdff1aSopenharmony_ci if (b[i] != 0xFF) 767cabdff1aSopenharmony_ci continue; 768cabdff1aSopenharmony_ci c = b[i + 1]; 769cabdff1aSopenharmony_ci switch (c) { 770cabdff1aSopenharmony_ci case SOI: 771cabdff1aSopenharmony_ci return 0; 772cabdff1aSopenharmony_ci case SOF0: 773cabdff1aSopenharmony_ci case SOF1: 774cabdff1aSopenharmony_ci case SOF2: 775cabdff1aSopenharmony_ci case SOF3: 776cabdff1aSopenharmony_ci case SOF5: 777cabdff1aSopenharmony_ci case SOF6: 778cabdff1aSopenharmony_ci case SOF7: 779cabdff1aSopenharmony_ci i += AV_RB16(&b[i + 2]) + 1; 780cabdff1aSopenharmony_ci if (state != SOI) 781cabdff1aSopenharmony_ci return 0; 782cabdff1aSopenharmony_ci state = SOF0; 783cabdff1aSopenharmony_ci break; 784cabdff1aSopenharmony_ci case SOS: 785cabdff1aSopenharmony_ci i += AV_RB16(&b[i + 2]) + 1; 786cabdff1aSopenharmony_ci if (state != SOF0 && state != SOS) 787cabdff1aSopenharmony_ci return 0; 788cabdff1aSopenharmony_ci state = SOS; 789cabdff1aSopenharmony_ci break; 790cabdff1aSopenharmony_ci case EOI: 791cabdff1aSopenharmony_ci if (state != SOS) 792cabdff1aSopenharmony_ci return 0; 793cabdff1aSopenharmony_ci state = EOI; 794cabdff1aSopenharmony_ci break; 795cabdff1aSopenharmony_ci case DQT: 796cabdff1aSopenharmony_ci case APP0: 797cabdff1aSopenharmony_ci if (AV_RL32(&b[i + 4]) == MKTAG('J','F','I','F')) 798cabdff1aSopenharmony_ci got_header = 1; 799cabdff1aSopenharmony_ci case APP1: 800cabdff1aSopenharmony_ci if (AV_RL32(&b[i + 4]) == MKTAG('E','x','i','f')) 801cabdff1aSopenharmony_ci got_header = 1; 802cabdff1aSopenharmony_ci case APP2: 803cabdff1aSopenharmony_ci case APP3: 804cabdff1aSopenharmony_ci case APP4: 805cabdff1aSopenharmony_ci case APP5: 806cabdff1aSopenharmony_ci case APP6: 807cabdff1aSopenharmony_ci case APP7: 808cabdff1aSopenharmony_ci case APP8: 809cabdff1aSopenharmony_ci case APP9: 810cabdff1aSopenharmony_ci case APP10: 811cabdff1aSopenharmony_ci case APP11: 812cabdff1aSopenharmony_ci case APP12: 813cabdff1aSopenharmony_ci case APP13: 814cabdff1aSopenharmony_ci case APP14: 815cabdff1aSopenharmony_ci case APP15: 816cabdff1aSopenharmony_ci case COM: 817cabdff1aSopenharmony_ci i += AV_RB16(&b[i + 2]) + 1; 818cabdff1aSopenharmony_ci break; 819cabdff1aSopenharmony_ci default: 820cabdff1aSopenharmony_ci if ( (c > TEM && c < SOF0) 821cabdff1aSopenharmony_ci || c == JPG) 822cabdff1aSopenharmony_ci return 0; 823cabdff1aSopenharmony_ci } 824cabdff1aSopenharmony_ci } 825cabdff1aSopenharmony_ci 826cabdff1aSopenharmony_ci if (state == EOI) 827cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 828cabdff1aSopenharmony_ci if (state == SOS) 829cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION / 2 + got_header; 830cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION / 8 + 1; 831cabdff1aSopenharmony_ci} 832cabdff1aSopenharmony_ci 833cabdff1aSopenharmony_cistatic int jpegls_probe(const AVProbeData *p) 834cabdff1aSopenharmony_ci{ 835cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 836cabdff1aSopenharmony_ci 837cabdff1aSopenharmony_ci if (AV_RB32(b) == 0xffd8fff7) 838cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 839cabdff1aSopenharmony_ci return 0; 840cabdff1aSopenharmony_ci} 841cabdff1aSopenharmony_ci 842cabdff1aSopenharmony_cistatic int jpegxl_probe(const AVProbeData *p) 843cabdff1aSopenharmony_ci{ 844cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 845cabdff1aSopenharmony_ci 846cabdff1aSopenharmony_ci /* ISOBMFF-based container */ 847cabdff1aSopenharmony_ci /* 0x4a584c20 == "JXL " */ 848cabdff1aSopenharmony_ci if (AV_RL64(b) == FF_JPEGXL_CONTAINER_SIGNATURE_LE) 849cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 850cabdff1aSopenharmony_ci /* Raw codestreams all start with 0xff0a */ 851cabdff1aSopenharmony_ci if (AV_RL16(b) != FF_JPEGXL_CODESTREAM_SIGNATURE_LE) 852cabdff1aSopenharmony_ci return 0; 853cabdff1aSopenharmony_ci#if CONFIG_IMAGE_JPEGXL_PIPE_DEMUXER 854cabdff1aSopenharmony_ci if (ff_jpegxl_verify_codestream_header(p->buf, p->buf_size) >= 0) 855cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX - 2; 856cabdff1aSopenharmony_ci#endif 857cabdff1aSopenharmony_ci return 0; 858cabdff1aSopenharmony_ci} 859cabdff1aSopenharmony_ci 860cabdff1aSopenharmony_cistatic int pcx_probe(const AVProbeData *p) 861cabdff1aSopenharmony_ci{ 862cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 863cabdff1aSopenharmony_ci 864cabdff1aSopenharmony_ci if ( p->buf_size < 128 865cabdff1aSopenharmony_ci || b[0] != 10 866cabdff1aSopenharmony_ci || b[1] > 5 867cabdff1aSopenharmony_ci || b[2] > 1 868cabdff1aSopenharmony_ci || av_popcount(b[3]) != 1 || b[3] > 8 869cabdff1aSopenharmony_ci || AV_RL16(&b[4]) > AV_RL16(&b[8]) 870cabdff1aSopenharmony_ci || AV_RL16(&b[6]) > AV_RL16(&b[10]) 871cabdff1aSopenharmony_ci || b[64]) 872cabdff1aSopenharmony_ci return 0; 873cabdff1aSopenharmony_ci b += 73; 874cabdff1aSopenharmony_ci while (++b < p->buf + 128) 875cabdff1aSopenharmony_ci if (*b) 876cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION / 4; 877cabdff1aSopenharmony_ci 878cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 879cabdff1aSopenharmony_ci} 880cabdff1aSopenharmony_ci 881cabdff1aSopenharmony_cistatic int qdraw_probe(const AVProbeData *p) 882cabdff1aSopenharmony_ci{ 883cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 884cabdff1aSopenharmony_ci 885cabdff1aSopenharmony_ci if ( p->buf_size >= 528 886cabdff1aSopenharmony_ci && (AV_RB64(b + 520) & 0xFFFFFFFFFFFF) == 0x001102ff0c00 887cabdff1aSopenharmony_ci && AV_RB16(b + 520) 888cabdff1aSopenharmony_ci && AV_RB16(b + 518)) 889cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX * 3 / 4; 890cabdff1aSopenharmony_ci if ( (AV_RB64(b + 8) & 0xFFFFFFFFFFFF) == 0x001102ff0c00 891cabdff1aSopenharmony_ci && AV_RB16(b + 8) 892cabdff1aSopenharmony_ci && AV_RB16(b + 6)) 893cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION / 4; 894cabdff1aSopenharmony_ci return 0; 895cabdff1aSopenharmony_ci} 896cabdff1aSopenharmony_ci 897cabdff1aSopenharmony_cistatic int pictor_probe(const AVProbeData *p) 898cabdff1aSopenharmony_ci{ 899cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 900cabdff1aSopenharmony_ci 901cabdff1aSopenharmony_ci if (AV_RL16(b) == 0x1234) 902cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION / 4; 903cabdff1aSopenharmony_ci return 0; 904cabdff1aSopenharmony_ci} 905cabdff1aSopenharmony_ci 906cabdff1aSopenharmony_cistatic int png_probe(const AVProbeData *p) 907cabdff1aSopenharmony_ci{ 908cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 909cabdff1aSopenharmony_ci 910cabdff1aSopenharmony_ci if (AV_RB64(b) == 0x89504e470d0a1a0a) 911cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX - 1; 912cabdff1aSopenharmony_ci return 0; 913cabdff1aSopenharmony_ci} 914cabdff1aSopenharmony_ci 915cabdff1aSopenharmony_cistatic int psd_probe(const AVProbeData *p) 916cabdff1aSopenharmony_ci{ 917cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 918cabdff1aSopenharmony_ci int ret = 0; 919cabdff1aSopenharmony_ci uint16_t color_mode; 920cabdff1aSopenharmony_ci 921cabdff1aSopenharmony_ci if (AV_RL32(b) == MKTAG('8','B','P','S')) { 922cabdff1aSopenharmony_ci ret += 1; 923cabdff1aSopenharmony_ci } else { 924cabdff1aSopenharmony_ci return 0; 925cabdff1aSopenharmony_ci } 926cabdff1aSopenharmony_ci 927cabdff1aSopenharmony_ci if ((b[4] == 0) && (b[5] == 1)) {/* version 1 is PSD, version 2 is PSB */ 928cabdff1aSopenharmony_ci ret += 1; 929cabdff1aSopenharmony_ci } else { 930cabdff1aSopenharmony_ci return 0; 931cabdff1aSopenharmony_ci } 932cabdff1aSopenharmony_ci 933cabdff1aSopenharmony_ci if ((AV_RL32(b+6) == 0) && (AV_RL16(b+10) == 0))/* reserved must be 0 */ 934cabdff1aSopenharmony_ci ret += 1; 935cabdff1aSopenharmony_ci 936cabdff1aSopenharmony_ci color_mode = AV_RB16(b+24); 937cabdff1aSopenharmony_ci if ((color_mode <= 9) && (color_mode != 5) && (color_mode != 6)) 938cabdff1aSopenharmony_ci ret += 1; 939cabdff1aSopenharmony_ci 940cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + ret; 941cabdff1aSopenharmony_ci} 942cabdff1aSopenharmony_ci 943cabdff1aSopenharmony_cistatic int sgi_probe(const AVProbeData *p) 944cabdff1aSopenharmony_ci{ 945cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 946cabdff1aSopenharmony_ci 947cabdff1aSopenharmony_ci if (AV_RB16(b) == 474 && 948cabdff1aSopenharmony_ci (b[2] & ~1) == 0 && 949cabdff1aSopenharmony_ci (b[3] & ~3) == 0 && b[3] && 950cabdff1aSopenharmony_ci (AV_RB16(b + 4) & ~7) == 0 && AV_RB16(b + 4)) 951cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 952cabdff1aSopenharmony_ci return 0; 953cabdff1aSopenharmony_ci} 954cabdff1aSopenharmony_ci 955cabdff1aSopenharmony_cistatic int sunrast_probe(const AVProbeData *p) 956cabdff1aSopenharmony_ci{ 957cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 958cabdff1aSopenharmony_ci 959cabdff1aSopenharmony_ci if (AV_RB32(b) == 0x59a66a95) 960cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 961cabdff1aSopenharmony_ci return 0; 962cabdff1aSopenharmony_ci} 963cabdff1aSopenharmony_ci 964cabdff1aSopenharmony_cistatic int svg_probe(const AVProbeData *p) 965cabdff1aSopenharmony_ci{ 966cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 967cabdff1aSopenharmony_ci const uint8_t *end = p->buf + p->buf_size; 968cabdff1aSopenharmony_ci 969cabdff1aSopenharmony_ci if (memcmp(p->buf, "<?xml", 5)) 970cabdff1aSopenharmony_ci return 0; 971cabdff1aSopenharmony_ci while (b < end) { 972cabdff1aSopenharmony_ci int inc = ff_subtitles_next_line(b); 973cabdff1aSopenharmony_ci if (!inc) 974cabdff1aSopenharmony_ci break; 975cabdff1aSopenharmony_ci b += inc; 976cabdff1aSopenharmony_ci if (b >= end - 4) 977cabdff1aSopenharmony_ci return 0; 978cabdff1aSopenharmony_ci if (!memcmp(b, "<svg", 4)) 979cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 980cabdff1aSopenharmony_ci } 981cabdff1aSopenharmony_ci return 0; 982cabdff1aSopenharmony_ci} 983cabdff1aSopenharmony_ci 984cabdff1aSopenharmony_cistatic int tiff_probe(const AVProbeData *p) 985cabdff1aSopenharmony_ci{ 986cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 987cabdff1aSopenharmony_ci 988cabdff1aSopenharmony_ci if (AV_RB32(b) == 0x49492a00 || 989cabdff1aSopenharmony_ci AV_RB32(b) == 0x4D4D002a) 990cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 991cabdff1aSopenharmony_ci return 0; 992cabdff1aSopenharmony_ci} 993cabdff1aSopenharmony_ci 994cabdff1aSopenharmony_cistatic int webp_probe(const AVProbeData *p) 995cabdff1aSopenharmony_ci{ 996cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 997cabdff1aSopenharmony_ci 998cabdff1aSopenharmony_ci if (AV_RB32(b) == 0x52494646 && 999cabdff1aSopenharmony_ci AV_RB32(b + 8) == 0x57454250) 1000cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX - 1; 1001cabdff1aSopenharmony_ci return 0; 1002cabdff1aSopenharmony_ci} 1003cabdff1aSopenharmony_ci 1004cabdff1aSopenharmony_cistatic int pnm_magic_check(const AVProbeData *p, int magic) 1005cabdff1aSopenharmony_ci{ 1006cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 1007cabdff1aSopenharmony_ci 1008cabdff1aSopenharmony_ci return b[0] == 'P' && b[1] == magic + '0'; 1009cabdff1aSopenharmony_ci} 1010cabdff1aSopenharmony_ci 1011cabdff1aSopenharmony_cistatic inline int pnm_probe(const AVProbeData *p) 1012cabdff1aSopenharmony_ci{ 1013cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 1014cabdff1aSopenharmony_ci 1015cabdff1aSopenharmony_ci while (b[2] == '\r') 1016cabdff1aSopenharmony_ci b++; 1017cabdff1aSopenharmony_ci if (b[2] == '\n' && (b[3] == '#' || (b[3] >= '0' && b[3] <= '9'))) 1018cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 2; 1019cabdff1aSopenharmony_ci return 0; 1020cabdff1aSopenharmony_ci} 1021cabdff1aSopenharmony_ci 1022cabdff1aSopenharmony_cistatic int pbm_probe(const AVProbeData *p) 1023cabdff1aSopenharmony_ci{ 1024cabdff1aSopenharmony_ci return pnm_magic_check(p, 1) || pnm_magic_check(p, 4) ? pnm_probe(p) : 0; 1025cabdff1aSopenharmony_ci} 1026cabdff1aSopenharmony_ci 1027cabdff1aSopenharmony_cistatic int pfm_probe(const AVProbeData *p) 1028cabdff1aSopenharmony_ci{ 1029cabdff1aSopenharmony_ci return pnm_magic_check(p, 'F' - '0') || 1030cabdff1aSopenharmony_ci pnm_magic_check(p, 'f' - '0') ? pnm_probe(p) : 0; 1031cabdff1aSopenharmony_ci} 1032cabdff1aSopenharmony_ci 1033cabdff1aSopenharmony_cistatic int phm_probe(const AVProbeData *p) 1034cabdff1aSopenharmony_ci{ 1035cabdff1aSopenharmony_ci return pnm_magic_check(p, 'H' - '0') || 1036cabdff1aSopenharmony_ci pnm_magic_check(p, 'h' - '0') ? pnm_probe(p) : 0; 1037cabdff1aSopenharmony_ci} 1038cabdff1aSopenharmony_ci 1039cabdff1aSopenharmony_cistatic inline int pgmx_probe(const AVProbeData *p) 1040cabdff1aSopenharmony_ci{ 1041cabdff1aSopenharmony_ci return pnm_magic_check(p, 2) || pnm_magic_check(p, 5) ? pnm_probe(p) : 0; 1042cabdff1aSopenharmony_ci} 1043cabdff1aSopenharmony_ci 1044cabdff1aSopenharmony_cistatic int pgm_probe(const AVProbeData *p) 1045cabdff1aSopenharmony_ci{ 1046cabdff1aSopenharmony_ci int ret = pgmx_probe(p); 1047cabdff1aSopenharmony_ci return ret && !av_match_ext(p->filename, "pgmyuv") ? ret : 0; 1048cabdff1aSopenharmony_ci} 1049cabdff1aSopenharmony_ci 1050cabdff1aSopenharmony_cistatic int pgmyuv_probe(const AVProbeData *p) // custom FFmpeg format recognized by file extension 1051cabdff1aSopenharmony_ci{ 1052cabdff1aSopenharmony_ci int ret = pgmx_probe(p); 1053cabdff1aSopenharmony_ci return ret && av_match_ext(p->filename, "pgmyuv") ? ret : 0; 1054cabdff1aSopenharmony_ci} 1055cabdff1aSopenharmony_ci 1056cabdff1aSopenharmony_cistatic int pgx_probe(const AVProbeData *p) 1057cabdff1aSopenharmony_ci{ 1058cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 1059cabdff1aSopenharmony_ci if (!memcmp(b, "PG ML ", 6)) 1060cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 1061cabdff1aSopenharmony_ci return 0; 1062cabdff1aSopenharmony_ci} 1063cabdff1aSopenharmony_ci 1064cabdff1aSopenharmony_cistatic int ppm_probe(const AVProbeData *p) 1065cabdff1aSopenharmony_ci{ 1066cabdff1aSopenharmony_ci return pnm_magic_check(p, 3) || pnm_magic_check(p, 6) ? pnm_probe(p) : 0; 1067cabdff1aSopenharmony_ci} 1068cabdff1aSopenharmony_ci 1069cabdff1aSopenharmony_cistatic int pam_probe(const AVProbeData *p) 1070cabdff1aSopenharmony_ci{ 1071cabdff1aSopenharmony_ci return pnm_magic_check(p, 7) ? pnm_probe(p) : 0; 1072cabdff1aSopenharmony_ci} 1073cabdff1aSopenharmony_ci 1074cabdff1aSopenharmony_cistatic int xbm_probe(const AVProbeData *p) 1075cabdff1aSopenharmony_ci{ 1076cabdff1aSopenharmony_ci if (!memcmp(p->buf, "/* XBM X10 format */", 20)) 1077cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX; 1078cabdff1aSopenharmony_ci 1079cabdff1aSopenharmony_ci if (!memcmp(p->buf, "#define", 7)) 1080cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX - 1; 1081cabdff1aSopenharmony_ci return 0; 1082cabdff1aSopenharmony_ci} 1083cabdff1aSopenharmony_ci 1084cabdff1aSopenharmony_cistatic int xpm_probe(const AVProbeData *p) 1085cabdff1aSopenharmony_ci{ 1086cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 1087cabdff1aSopenharmony_ci 1088cabdff1aSopenharmony_ci if (AV_RB64(b) == 0x2f2a2058504d202a && *(b+8) == '/') 1089cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX - 1; 1090cabdff1aSopenharmony_ci return 0; 1091cabdff1aSopenharmony_ci} 1092cabdff1aSopenharmony_ci 1093cabdff1aSopenharmony_cistatic int xwd_probe(const AVProbeData *p) 1094cabdff1aSopenharmony_ci{ 1095cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 1096cabdff1aSopenharmony_ci unsigned width, bpp, bpad, lsize; 1097cabdff1aSopenharmony_ci 1098cabdff1aSopenharmony_ci if ( p->buf_size < XWD_HEADER_SIZE 1099cabdff1aSopenharmony_ci || AV_RB32(b ) < XWD_HEADER_SIZE // header size 1100cabdff1aSopenharmony_ci || AV_RB32(b + 4) != XWD_VERSION // version 1101cabdff1aSopenharmony_ci || AV_RB32(b + 8) != XWD_Z_PIXMAP // format 1102cabdff1aSopenharmony_ci || AV_RB32(b + 12) > 32 || !AV_RB32(b + 12) // depth 1103cabdff1aSopenharmony_ci || AV_RB32(b + 16) == 0 // width 1104cabdff1aSopenharmony_ci || AV_RB32(b + 20) == 0 // height 1105cabdff1aSopenharmony_ci || AV_RB32(b + 28) > 1 // byteorder 1106cabdff1aSopenharmony_ci || AV_RB32(b + 32) & ~56 || av_popcount(AV_RB32(b + 32)) != 1 // bitmap unit 1107cabdff1aSopenharmony_ci || AV_RB32(b + 36) > 1 // bitorder 1108cabdff1aSopenharmony_ci || AV_RB32(b + 40) & ~56 || av_popcount(AV_RB32(b + 40)) != 1 // padding 1109cabdff1aSopenharmony_ci || AV_RB32(b + 44) > 32 || !AV_RB32(b + 44) // bpp 1110cabdff1aSopenharmony_ci || AV_RB32(b + 68) > 256) // colours 1111cabdff1aSopenharmony_ci return 0; 1112cabdff1aSopenharmony_ci 1113cabdff1aSopenharmony_ci width = AV_RB32(b + 16); 1114cabdff1aSopenharmony_ci bpad = AV_RB32(b + 40); 1115cabdff1aSopenharmony_ci bpp = AV_RB32(b + 44); 1116cabdff1aSopenharmony_ci lsize = AV_RB32(b + 48); 1117cabdff1aSopenharmony_ci if (lsize < FFALIGN(width * bpp, bpad) >> 3) 1118cabdff1aSopenharmony_ci return 0; 1119cabdff1aSopenharmony_ci 1120cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX / 2 + 1; 1121cabdff1aSopenharmony_ci} 1122cabdff1aSopenharmony_ci 1123cabdff1aSopenharmony_cistatic int gif_probe(const AVProbeData *p) 1124cabdff1aSopenharmony_ci{ 1125cabdff1aSopenharmony_ci /* check magick */ 1126cabdff1aSopenharmony_ci if (memcmp(p->buf, gif87a_sig, 6) && memcmp(p->buf, gif89a_sig, 6)) 1127cabdff1aSopenharmony_ci return 0; 1128cabdff1aSopenharmony_ci 1129cabdff1aSopenharmony_ci /* width or height contains zero? */ 1130cabdff1aSopenharmony_ci if (!AV_RL16(&p->buf[6]) || !AV_RL16(&p->buf[8])) 1131cabdff1aSopenharmony_ci return 0; 1132cabdff1aSopenharmony_ci 1133cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX - 1; 1134cabdff1aSopenharmony_ci} 1135cabdff1aSopenharmony_ci 1136cabdff1aSopenharmony_cistatic int photocd_probe(const AVProbeData *p) 1137cabdff1aSopenharmony_ci{ 1138cabdff1aSopenharmony_ci if (!memcmp(p->buf, "PCD_OPA", 7)) 1139cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX - 1; 1140cabdff1aSopenharmony_ci 1141cabdff1aSopenharmony_ci if (p->buf_size < 0x807 || memcmp(p->buf + 0x800, "PCD_IPI", 7)) 1142cabdff1aSopenharmony_ci return 0; 1143cabdff1aSopenharmony_ci 1144cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX - 1; 1145cabdff1aSopenharmony_ci} 1146cabdff1aSopenharmony_ci 1147cabdff1aSopenharmony_cistatic int qoi_probe(const AVProbeData *p) 1148cabdff1aSopenharmony_ci{ 1149cabdff1aSopenharmony_ci if (memcmp(p->buf, "qoif", 4)) 1150cabdff1aSopenharmony_ci return 0; 1151cabdff1aSopenharmony_ci 1152cabdff1aSopenharmony_ci if (AV_RB32(p->buf + 4) == 0 || AV_RB32(p->buf + 8) == 0) 1153cabdff1aSopenharmony_ci return 0; 1154cabdff1aSopenharmony_ci 1155cabdff1aSopenharmony_ci if (p->buf[12] != 3 && p->buf[12] != 4) 1156cabdff1aSopenharmony_ci return 0; 1157cabdff1aSopenharmony_ci 1158cabdff1aSopenharmony_ci if (p->buf[13] > 1) 1159cabdff1aSopenharmony_ci return 0; 1160cabdff1aSopenharmony_ci 1161cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX - 1; 1162cabdff1aSopenharmony_ci} 1163cabdff1aSopenharmony_ci 1164cabdff1aSopenharmony_cistatic int gem_probe(const AVProbeData *p) 1165cabdff1aSopenharmony_ci{ 1166cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 1167cabdff1aSopenharmony_ci if ( AV_RB16(b ) >= 1 && AV_RB16(b ) <= 3 && 1168cabdff1aSopenharmony_ci AV_RB16(b + 2) >= 8 && AV_RB16(b + 2) <= 779 && 1169cabdff1aSopenharmony_ci (AV_RB16(b + 4) > 0 && AV_RB16(b + 4) <= 32) && /* planes */ 1170cabdff1aSopenharmony_ci (AV_RB16(b + 6) > 0 && AV_RB16(b + 6) <= 8) && /* pattern_size */ 1171cabdff1aSopenharmony_ci AV_RB16(b + 8) && 1172cabdff1aSopenharmony_ci AV_RB16(b + 10) && 1173cabdff1aSopenharmony_ci AV_RB16(b + 12) && 1174cabdff1aSopenharmony_ci AV_RB16(b + 14)) { 1175cabdff1aSopenharmony_ci if (AV_RN32(b + 16) == AV_RN32("STTT") || 1176cabdff1aSopenharmony_ci AV_RN32(b + 16) == AV_RN32("TIMG") || 1177cabdff1aSopenharmony_ci AV_RN32(b + 16) == AV_RN32("XIMG")) 1178cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION + 1; 1179cabdff1aSopenharmony_ci return AVPROBE_SCORE_EXTENSION / 4; 1180cabdff1aSopenharmony_ci } 1181cabdff1aSopenharmony_ci return 0; 1182cabdff1aSopenharmony_ci} 1183cabdff1aSopenharmony_ci 1184cabdff1aSopenharmony_cistatic int vbn_probe(const AVProbeData *p) 1185cabdff1aSopenharmony_ci{ 1186cabdff1aSopenharmony_ci const uint8_t *b = p->buf; 1187cabdff1aSopenharmony_ci if (AV_RL32(b ) == VBN_MAGIC && 1188cabdff1aSopenharmony_ci AV_RL32(b + 4) == VBN_MAJOR && 1189cabdff1aSopenharmony_ci AV_RL32(b + 8) == VBN_MINOR) 1190cabdff1aSopenharmony_ci return AVPROBE_SCORE_MAX - 1; 1191cabdff1aSopenharmony_ci return 0; 1192cabdff1aSopenharmony_ci} 1193cabdff1aSopenharmony_ci 1194cabdff1aSopenharmony_ci#define IMAGEAUTO_DEMUXER_0(imgname, codecid) 1195cabdff1aSopenharmony_ci#define IMAGEAUTO_DEMUXER_1(imgname, codecid)\ 1196cabdff1aSopenharmony_ciconst AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\ 1197cabdff1aSopenharmony_ci .name = AV_STRINGIFY(imgname) "_pipe",\ 1198cabdff1aSopenharmony_ci .long_name = NULL_IF_CONFIG_SMALL("piped " AV_STRINGIFY(imgname) " sequence"),\ 1199cabdff1aSopenharmony_ci .priv_data_size = sizeof(VideoDemuxData),\ 1200cabdff1aSopenharmony_ci .read_probe = imgname ## _probe,\ 1201cabdff1aSopenharmony_ci .read_header = ff_img_read_header,\ 1202cabdff1aSopenharmony_ci .read_packet = ff_img_read_packet,\ 1203cabdff1aSopenharmony_ci .priv_class = &imagepipe_class,\ 1204cabdff1aSopenharmony_ci .flags = AVFMT_GENERIC_INDEX, \ 1205cabdff1aSopenharmony_ci .raw_codec_id = codecid,\ 1206cabdff1aSopenharmony_ci}; 1207cabdff1aSopenharmony_ci 1208cabdff1aSopenharmony_ci#define IMAGEAUTO_DEMUXER_2(imgname, codecid, enabled) \ 1209cabdff1aSopenharmony_ci IMAGEAUTO_DEMUXER_ ## enabled(imgname, codecid) 1210cabdff1aSopenharmony_ci#define IMAGEAUTO_DEMUXER_3(imgname, codecid, config) \ 1211cabdff1aSopenharmony_ci IMAGEAUTO_DEMUXER_2(imgname, codecid, config) 1212cabdff1aSopenharmony_ci#define IMAGEAUTO_DEMUXER_EXT(imgname, codecid, uppercase_name) \ 1213cabdff1aSopenharmony_ci IMAGEAUTO_DEMUXER_3(imgname, AV_CODEC_ID_ ## codecid, \ 1214cabdff1aSopenharmony_ci CONFIG_IMAGE_ ## uppercase_name ## _PIPE_DEMUXER) 1215cabdff1aSopenharmony_ci#define IMAGEAUTO_DEMUXER(imgname, codecid) \ 1216cabdff1aSopenharmony_ci IMAGEAUTO_DEMUXER_EXT(imgname, codecid, codecid) 1217cabdff1aSopenharmony_ci 1218cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(bmp, BMP) 1219cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(cri, CRI) 1220cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(dds, DDS) 1221cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(dpx, DPX) 1222cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(exr, EXR) 1223cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(gem, GEM) 1224cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(gif, GIF) 1225cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER_EXT(j2k, JPEG2000, J2K) 1226cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER_EXT(jpeg, MJPEG, JPEG) 1227cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(jpegls, JPEGLS) 1228cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(jpegxl, JPEGXL) 1229cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(pam, PAM) 1230cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(pbm, PBM) 1231cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(pcx, PCX) 1232cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(pfm, PFM) 1233cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(pgm, PGM) 1234cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(pgmyuv, PGMYUV) 1235cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(pgx, PGX) 1236cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(phm, PHM) 1237cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(photocd, PHOTOCD) 1238cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(pictor, PICTOR) 1239cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(png, PNG) 1240cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(ppm, PPM) 1241cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(psd, PSD) 1242cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(qdraw, QDRAW) 1243cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(qoi, QOI) 1244cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(sgi, SGI) 1245cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(sunrast, SUNRAST) 1246cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(svg, SVG) 1247cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(tiff, TIFF) 1248cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(vbn, VBN) 1249cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(webp, WEBP) 1250cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(xbm, XBM) 1251cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(xpm, XPM) 1252cabdff1aSopenharmony_ciIMAGEAUTO_DEMUXER(xwd, XWD) 1253