img2dec.c 22.7 KB
Newer Older
1 2 3 4 5
/*
 * Image format
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
 * Copyright (c) 2004 Michael Niedermayer
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9 10 11 12
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14 15 16 17 18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * 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 21 22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

23
#define _BSD_SOURCE
A
Andrey Utkin 已提交
24
#include <sys/stat.h>
25 26 27 28 29
#include "libavutil/avstring.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavutil/parseutils.h"
30
#include "libavutil/intreadwrite.h"
31
#include "avformat.h"
32
#include "avio_internal.h"
33
#include "internal.h"
34
#include "img2.h"
35

36
#if HAVE_GLOB
37 38 39 40 41 42 43 44 45 46
/* Locally define as 0 (bitwise-OR no-op) any missing glob options that
   are non-posix glibc/bsd extensions. */
#ifndef GLOB_NOMAGIC
#define GLOB_NOMAGIC 0
#endif
#ifndef GLOB_BRACE
#define GLOB_BRACE 0
#endif

#endif /* HAVE_GLOB */
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

static const int sizes[][2] = {
    { 640, 480 },
    { 720, 480 },
    { 720, 576 },
    { 352, 288 },
    { 352, 240 },
    { 160, 128 },
    { 512, 384 },
    { 640, 352 },
    { 640, 240 },
};

static int infer_size(int *width_ptr, int *height_ptr, int size)
{
    int i;

D
Diego Biurrun 已提交
64
    for (i = 0; i < FF_ARRAY_ELEMS(sizes); i++) {
65
        if ((sizes[i][0] * sizes[i][1]) == size) {
D
Diego Biurrun 已提交
66
            *width_ptr  = sizes[i][0];
67 68 69 70
            *height_ptr = sizes[i][1];
            return 0;
        }
    }
D
Diego Biurrun 已提交
71

72 73 74
    return -1;
}

75 76 77
static int is_glob(const char *path)
{
#if HAVE_GLOB
78 79 80 81 82 83 84 85 86 87 88
    size_t span = 0;
    const char *p = path;

    while (p = strchr(p, '%')) {
        if (*(++p) == '%') {
            ++p;
            continue;
        }
        if (span = strspn(p, "*?[]{}"))
            break;
    }
89
    /* Did we hit a glob char or get to the end? */
90
    return span != 0;
91 92 93 94 95
#else
    return 0;
#endif
}

96 97 98 99 100 101 102 103 104
/**
 * Get index range of image files matched by path.
 *
 * @param pfirst_index pointer to index updated with the first number in the range
 * @param plast_index  pointer to index updated with the last number in the range
 * @param path         path which has to be matched by the image files in the range
 * @param start_index  minimum accepted value for the first index in the range
 * @return -1 if no image file could be found
 */
105
static int find_image_range(int *pfirst_index, int *plast_index,
106
                            const char *path, int start_index, int start_index_range)
107 108 109 110 111
{
    char buf[1024];
    int range, last_index, range1, first_index;

    /* find the first image */
112
    for (first_index = start_index; first_index < start_index + start_index_range; first_index++) {
D
Diego Biurrun 已提交
113
        if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0) {
114
            *pfirst_index =
D
Diego Biurrun 已提交
115
            *plast_index  = 1;
116 117 118 119 120 121 122
            if (avio_check(buf, AVIO_FLAG_READ) > 0)
                return 0;
            return -1;
        }
        if (avio_check(buf, AVIO_FLAG_READ) > 0)
            break;
    }
123
    if (first_index == start_index + start_index_range)
124 125 126 127
        goto fail;

    /* find the last image */
    last_index = first_index;
D
Diego Biurrun 已提交
128
    for (;;) {
129
        range = 0;
D
Diego Biurrun 已提交
130
        for (;;) {
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
            if (!range)
                range1 = 1;
            else
                range1 = 2 * range;
            if (av_get_frame_filename(buf, sizeof(buf), path,
                                      last_index + range1) < 0)
                goto fail;
            if (avio_check(buf, AVIO_FLAG_READ) <= 0)
                break;
            range = range1;
            /* just in case... */
            if (range >= (1 << 30))
                goto fail;
        }
        /* we are sure than image last_index + range exists */
        if (!range)
            break;
        last_index += range;
    }
    *pfirst_index = first_index;
D
Diego Biurrun 已提交
151
    *plast_index  = last_index;
152
    return 0;
D
Diego Biurrun 已提交
153 154

fail:
155 156 157
    return -1;
}

D
Diego Biurrun 已提交
158
static int img_read_probe(AVProbeData *p)
159 160 161 162
{
    if (p->filename && ff_guess_image2_codec(p->filename)) {
        if (av_filename_number_test(p->filename))
            return AVPROBE_SCORE_MAX;
163 164
        else if (is_glob(p->filename))
            return AVPROBE_SCORE_MAX;
165 166
        else if (p->buf_size == 0)
            return 0;
167
        else if (av_match_ext(p->filename, "raw") || av_match_ext(p->filename, "gif"))
168
            return 5;
169
        else
170
            return AVPROBE_SCORE_EXTENSION;
171 172 173 174
    }
    return 0;
}

175
int ff_img_read_header(AVFormatContext *s1)
176 177
{
    VideoDemuxData *s = s1->priv_data;
178
    int first_index, last_index;
179
    AVStream *st;
180
    enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
181 182 183 184 185 186 187 188

    s1->ctx_flags |= AVFMTCTX_NOHEADER;

    st = avformat_new_stream(s1, NULL);
    if (!st) {
        return AVERROR(ENOMEM);
    }

D
Diego Biurrun 已提交
189 190 191 192
    if (s->pixel_format &&
        (pix_fmt = av_get_pix_fmt(s->pixel_format)) == AV_PIX_FMT_NONE) {
        av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n",
               s->pixel_format);
193 194 195 196 197
        return AVERROR(EINVAL);
    }

    av_strlcpy(s->path, s1->filename, sizeof(s->path));
    s->img_number = 0;
D
Diego Biurrun 已提交
198
    s->img_count  = 0;
199 200 201 202

    /* find format */
    if (s1->iformat->flags & AVFMT_NOFILE)
        s->is_pipe = 0;
D
Diego Biurrun 已提交
203 204
    else {
        s->is_pipe       = 1;
205 206 207
        st->need_parsing = AVSTREAM_PARSE_FULL;
    }

208 209 210 211 212 213 214
    if (s->ts_from_file == 2) {
#if !HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
        av_log(s1, AV_LOG_ERROR, "POSIX.1-2008 not supported, nanosecond file timestamps unavailable\n");
        return AVERROR(ENOSYS);
#endif
        avpriv_set_pts_info(st, 64, 1, 1000000000);
    } else if (s->ts_from_file)
215
        avpriv_set_pts_info(st, 64, 1, 1);
A
Andrey Utkin 已提交
216
    else
217
        avpriv_set_pts_info(st, 64, s->framerate.den, s->framerate.num);
218

219 220 221
    if (s->width && s->height) {
        st->codec->width  = s->width;
        st->codec->height = s->height;
222 223 224
    }

    if (!s->is_pipe) {
225
        if (s->pattern_type == PT_GLOB_SEQUENCE) {
226 227
        s->use_glob = is_glob(s->path);
        if (s->use_glob) {
228
            char *p = s->path, *q, *dup;
229
            int gerr;
230

231 232 233
            av_log(s1, AV_LOG_WARNING, "Pattern type 'glob_sequence' is deprecated: "
                   "use pattern_type 'glob' instead\n");
#if HAVE_GLOB
234 235 236 237 238 239 240 241 242 243 244 245 246 247
            dup = q = av_strdup(p);
            while (*q) {
                /* Do we have room for the next char and a \ insertion? */
                if ((p - s->path) >= (sizeof(s->path) - 2))
                  break;
                if (*q == '%' && strspn(q + 1, "%*?[]{}"))
                    ++q;
                else if (strspn(q, "\\*?[]{}"))
                    *p++ = '\\';
                *p++ = *q++;
            }
            *p = 0;
            av_free(dup);

248
            gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate);
249 250 251 252 253 254
            if (gerr != 0) {
                return AVERROR(ENOENT);
            }
            first_index = 0;
            last_index = s->globstate.gl_pathc - 1;
#endif
255 256 257
        }
        }
        if ((s->pattern_type == PT_GLOB_SEQUENCE && !s->use_glob) || s->pattern_type == PT_SEQUENCE) {
258
            if (find_image_range(&first_index, &last_index, s->path,
259
                                 s->start_number, s->start_number_range) < 0) {
260
                av_log(s1, AV_LOG_ERROR,
261
                       "Could find no file with path '%s' and index in the range %d-%d\n",
262
                       s->path, s->start_number, s->start_number + s->start_number_range - 1);
263
                return AVERROR(ENOENT);
264
            }
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
        } else if (s->pattern_type == PT_GLOB) {
#if HAVE_GLOB
            int gerr;
            gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate);
            if (gerr != 0) {
                return AVERROR(ENOENT);
            }
            first_index = 0;
            last_index = s->globstate.gl_pathc - 1;
            s->use_glob = 1;
#else
            av_log(s1, AV_LOG_ERROR,
                   "Pattern type 'glob' was selected but globbing "
                   "is not supported by this libavformat build\n");
            return AVERROR(ENOSYS);
#endif
        } else if (s->pattern_type != PT_GLOB_SEQUENCE) {
            av_log(s1, AV_LOG_ERROR,
                   "Unknown value '%d' for pattern_type option\n", s->pattern_type);
            return AVERROR(EINVAL);
285
        }
D
Diego Biurrun 已提交
286 287
        s->img_first  = first_index;
        s->img_last   = last_index;
288 289
        s->img_number = first_index;
        /* compute duration */
290 291 292 293
        if (!s->ts_from_file) {
            st->start_time = 0;
            st->duration   = last_index - first_index + 1;
        }
294 295
    }

D
Diego Biurrun 已提交
296
    if (s1->video_codec_id) {
297
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
D
Diego Biurrun 已提交
298 299
        st->codec->codec_id   = s1->video_codec_id;
    } else if (s1->audio_codec_id) {
300
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
D
Diego Biurrun 已提交
301
        st->codec->codec_id   = s1->audio_codec_id;
302 303 304
    } else if (s1->iformat->raw_codec_id) {
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
        st->codec->codec_id   = s1->iformat->raw_codec_id;
D
Diego Biurrun 已提交
305
    } else {
306 307
        const char *str = strrchr(s->path, '.');
        s->split_planes       = str && !av_strcasecmp(str + 1, "y");
308
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
309
        if (s1->pb) {
310
            int probe_buffer_size = 2048;
311
            uint8_t *probe_buffer = av_realloc(NULL, probe_buffer_size + AVPROBE_PADDING_SIZE);
312
            AVInputFormat *fmt = NULL;
313
            AVProbeData pd = { 0 };
314 315 316 317 318 319 320 321 322 323

            if (!probe_buffer)
                return AVERROR(ENOMEM);

            probe_buffer_size = avio_read(s1->pb, probe_buffer, probe_buffer_size);
            if (probe_buffer_size < 0) {
                av_free(probe_buffer);
                return probe_buffer_size;
            }
            memset(probe_buffer + probe_buffer_size, 0, AVPROBE_PADDING_SIZE);
324 325

            pd.buf = probe_buffer;
326
            pd.buf_size = probe_buffer_size;
327 328 329 330 331 332 333 334 335 336 337 338 339
            pd.filename = s1->filename;

            while ((fmt = av_iformat_next(fmt))) {
                if (fmt->read_header != ff_img_read_header ||
                    !fmt->read_probe ||
                    (fmt->flags & AVFMT_NOFILE) ||
                    !fmt->raw_codec_id)
                    continue;
                if (fmt->read_probe(&pd) > 0) {
                    st->codec->codec_id = fmt->raw_codec_id;
                    break;
                }
            }
340
            ffio_rewind_with_probe_data(s1->pb, &probe_buffer, probe_buffer_size);
341 342 343
        }
        if (st->codec->codec_id == AV_CODEC_ID_NONE)
            st->codec->codec_id = ff_guess_image2_codec(s->path);
344 345
        if (st->codec->codec_id == AV_CODEC_ID_LJPEG)
            st->codec->codec_id = AV_CODEC_ID_MJPEG;
346 347
        if (st->codec->codec_id == AV_CODEC_ID_ALIAS_PIX) // we cannot distingiush this from BRENDER_PIX
            st->codec->codec_id = AV_CODEC_ID_NONE;
348
    }
D
Diego Biurrun 已提交
349 350
    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
        pix_fmt != AV_PIX_FMT_NONE)
351 352 353 354 355
        st->codec->pix_fmt = pix_fmt;

    return 0;
}

356
int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt)
357 358
{
    VideoDemuxData *s = s1->priv_data;
359 360
    char filename_bytes[1024];
    char *filename = filename_bytes;
361
    int i;
D
Diego Biurrun 已提交
362 363 364
    int size[3]           = { 0 }, ret[3] = { 0 };
    AVIOContext *f[3]     = { NULL };
    AVCodecContext *codec = s1->streams[0]->codec;
365 366 367 368 369 370 371 372

    if (!s->is_pipe) {
        /* loop over input */
        if (s->loop && s->img_number > s->img_last) {
            s->img_number = s->img_first;
        }
        if (s->img_number > s->img_last)
            return AVERROR_EOF;
373 374 375 376 377 378
        if (s->use_glob) {
#if HAVE_GLOB
            filename = s->globstate.gl_pathv[s->img_number];
#endif
        } else {
        if (av_get_frame_filename(filename_bytes, sizeof(filename_bytes),
D
Diego Biurrun 已提交
379 380
                                  s->path,
                                  s->img_number) < 0 && s->img_number > 1)
381
            return AVERROR(EIO);
382
        }
D
Diego Biurrun 已提交
383
        for (i = 0; i < 3; i++) {
384 385
            if (avio_open2(&f[i], filename, AVIO_FLAG_READ,
                           &s1->interrupt_callback, NULL) < 0) {
D
Diego Biurrun 已提交
386
                if (i >= 1)
387
                    break;
D
Diego Biurrun 已提交
388 389
                av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n",
                       filename);
390 391
                return AVERROR(EIO);
            }
D
Diego Biurrun 已提交
392
            size[i] = avio_size(f[i]);
393

394
            if (!s->split_planes)
395
                break;
D
Diego Biurrun 已提交
396
            filename[strlen(filename) - 1] = 'U' + i;
397 398
        }

399
        if (codec->codec_id == AV_CODEC_ID_NONE) {
400
            AVProbeData pd = { 0 };
401
            AVInputFormat *ifmt;
402
            uint8_t header[PROBE_BUF_MIN + AVPROBE_PADDING_SIZE];
403 404 405
            int ret;
            int score = 0;

406
            ret = avio_read(f[0], header, PROBE_BUF_MIN);
407 408
            if (ret < 0)
                return ret;
409
            memset(header + ret, 0, sizeof(header) - ret);
410 411 412 413 414 415 416 417 418 419
            avio_skip(f[0], -ret);
            pd.buf = header;
            pd.buf_size = ret;
            pd.filename = filename;

            ifmt = av_probe_input_format3(&pd, 1, &score);
            if (ifmt && ifmt->read_packet == ff_img_read_packet && ifmt->raw_codec_id)
                codec->codec_id = ifmt->raw_codec_id;
        }

D
Diego Biurrun 已提交
420
        if (codec->codec_id == AV_CODEC_ID_RAWVIDEO && !codec->width)
421 422 423
            infer_size(&codec->width, &codec->height, size[0]);
    } else {
        f[0] = s1->pb;
424
        if (avio_feof(f[0]))
425
            return AVERROR_EOF;
426 427
        if (s->frame_size > 0) {
            size[0] = s->frame_size;
428 429
        } else if (!s1->streams[0]->parser) {
            size[0] = avio_size(s1->pb);
430
        } else {
431
            size[0] = 4096;
432
        }
433 434
    }

435 436
    if (av_new_packet(pkt, size[0] + size[1] + size[2]) < 0)
        return AVERROR(ENOMEM);
437
    pkt->stream_index = 0;
D
Diego Biurrun 已提交
438
    pkt->flags       |= AV_PKT_FLAG_KEY;
A
Andrey Utkin 已提交
439 440 441 442 443
    if (s->ts_from_file) {
        struct stat img_stat;
        if (stat(filename, &img_stat))
            return AVERROR(EIO);
        pkt->pts = (int64_t)img_stat.st_mtime;
444 445 446 447
#if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
        if (s->ts_from_file == 2)
            pkt->pts = 1000000000*pkt->pts + img_stat.st_mtim.tv_nsec;
#endif
448
        av_add_index_entry(s1->streams[0], s->img_number, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
A
Andrey Utkin 已提交
449
    } else if (!s->is_pipe) {
450
        pkt->pts      = s->pts;
A
Andrey Utkin 已提交
451
    }
452

D
Diego Biurrun 已提交
453 454 455 456
    pkt->size = 0;
    for (i = 0; i < 3; i++) {
        if (f[i]) {
            ret[i] = avio_read(f[i], pkt->data + pkt->size, size[i]);
457 458
            if (!s->is_pipe)
                avio_close(f[i]);
D
Diego Biurrun 已提交
459
            if (ret[i] > 0)
460 461 462 463
                pkt->size += ret[i];
        }
    }

D
Diego Biurrun 已提交
464
    if (ret[0] <= 0 || ret[1] < 0 || ret[2] < 0) {
465
        av_free_packet(pkt);
466 467 468 469 470 471 472
        if (ret[0] < 0) {
            return ret[0];
        } else if (ret[1] < 0) {
            return ret[1];
        } else if (ret[2] < 0)
            return ret[2];
        return AVERROR_EOF;
473 474 475
    } else {
        s->img_count++;
        s->img_number++;
476
        s->pts++;
477 478 479 480
        return 0;
    }
}

481
static int img_read_close(struct AVFormatContext* s1)
482 483 484 485 486 487 488 489 490 491
{
    VideoDemuxData *s = s1->priv_data;
#if HAVE_GLOB
    if (s->use_glob) {
        globfree(&s->globstate);
    }
#endif
    return 0;
}

P
Paul B Mahol 已提交
492 493 494
static int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
{
    VideoDemuxData *s1 = s->priv_data;
495 496 497 498 499 500 501 502 503
    AVStream *st = s->streams[0];

    if (s1->ts_from_file) {
        int index = av_index_search_timestamp(st, timestamp, flags);
        if(index < 0)
            return -1;
        s1->img_number = st->index_entries[index].pos;
        return 0;
    }
P
Paul B Mahol 已提交
504

505
    if (timestamp < 0 || !s1->loop && timestamp > s1->img_last - s1->img_first)
P
Paul B Mahol 已提交
506
        return -1;
507 508
    s1->img_number = timestamp%(s1->img_last - s1->img_first + 1) + s1->img_first;
    s1->pts = timestamp;
P
Paul B Mahol 已提交
509 510 511
    return 0;
}

512 513
#define OFFSET(x) offsetof(VideoDemuxData, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
514
const AVOption ff_img_options[] = {
515
    { "framerate",    "set the video framerate",             OFFSET(framerate),    AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0,   DEC },
516
    { "loop",         "force loop over input file sequence", OFFSET(loop),         AV_OPT_TYPE_INT,    {.i64 = 0   }, 0, 1,       DEC },
517

518
    { "pattern_type", "set pattern type",                    OFFSET(pattern_type), AV_OPT_TYPE_INT,    {.i64=PT_GLOB_SEQUENCE}, 0,       INT_MAX, DEC, "pattern_type"},
519 520 521
    { "glob_sequence","select glob/sequence pattern type",   0, AV_OPT_TYPE_CONST,  {.i64=PT_GLOB_SEQUENCE}, INT_MIN, INT_MAX, DEC, "pattern_type" },
    { "glob",         "select glob pattern type",            0, AV_OPT_TYPE_CONST,  {.i64=PT_GLOB         }, INT_MIN, INT_MAX, DEC, "pattern_type" },
    { "sequence",     "select sequence pattern type",        0, AV_OPT_TYPE_CONST,  {.i64=PT_SEQUENCE     }, INT_MIN, INT_MAX, DEC, "pattern_type" },
522

523 524
    { "pixel_format", "set video pixel format",              OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0,       DEC },
    { "start_number", "set first number in the sequence",    OFFSET(start_number), AV_OPT_TYPE_INT,    {.i64 = 0   }, 0, INT_MAX, DEC },
525
    { "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 },
526
    { "video_size",   "set video size",                      OFFSET(width),        AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0,   DEC },
527
    { "frame_size",   "force frame size in bytes",           OFFSET(frame_size),   AV_OPT_TYPE_INT,    {.i64 = 0   }, 0, INT_MAX, DEC },
528 529
    { "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" },
    { "none", "none",                   0, AV_OPT_TYPE_CONST,    {.i64 = 0   }, 0, 2,       DEC, "ts_type" },
M
Michael Niedermayer 已提交
530 531
    { "sec",  "second precision",       0, AV_OPT_TYPE_CONST,    {.i64 = 1   }, 0, 2,       DEC, "ts_type" },
    { "ns",   "nano second precision",  0, AV_OPT_TYPE_CONST,    {.i64 = 2   }, 0, 2,       DEC, "ts_type" },
532 533 534 535 536 537 538
    { NULL },
};

#if CONFIG_IMAGE2_DEMUXER
static const AVClass img2_class = {
    .class_name = "image2 demuxer",
    .item_name  = av_default_item_name,
539
    .option     = ff_img_options,
540 541 542 543 544 545
    .version    = LIBAVUTIL_VERSION_INT,
};
AVInputFormat ff_image2_demuxer = {
    .name           = "image2",
    .long_name      = NULL_IF_CONFIG_SMALL("image2 sequence"),
    .priv_data_size = sizeof(VideoDemuxData),
D
Diego Biurrun 已提交
546
    .read_probe     = img_read_probe,
547 548
    .read_header    = ff_img_read_header,
    .read_packet    = ff_img_read_packet,
549
    .read_close     = img_read_close,
P
Paul B Mahol 已提交
550
    .read_seek      = img_read_seek,
551 552 553 554 555 556 557 558
    .flags          = AVFMT_NOFILE,
    .priv_class     = &img2_class,
};
#endif
#if CONFIG_IMAGE2PIPE_DEMUXER
static const AVClass img2pipe_class = {
    .class_name = "image2pipe demuxer",
    .item_name  = av_default_item_name,
559
    .option     = ff_img_options,
560 561 562 563 564 565
    .version    = LIBAVUTIL_VERSION_INT,
};
AVInputFormat ff_image2pipe_demuxer = {
    .name           = "image2pipe",
    .long_name      = NULL_IF_CONFIG_SMALL("piped image2 sequence"),
    .priv_data_size = sizeof(VideoDemuxData),
566 567
    .read_header    = ff_img_read_header,
    .read_packet    = ff_img_read_packet,
568 569 570
    .priv_class     = &img2pipe_class,
};
#endif
571 572 573 574

static int bmp_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;
575
    int ihsize;
576

577 578 579 580 581 582 583 584
    if (AV_RB16(b) != 0x424d)
        return 0;

    ihsize = AV_RL32(b+14);
    if (ihsize < 12 || ihsize > 255)
        return 0;

    if (!AV_RN32(b + 6)) {
585
        return AVPROBE_SCORE_EXTENSION - 1; // lower than extension as bmp pipe has bugs
586 587 588
    } else {
        return AVPROBE_SCORE_EXTENSION / 4;
    }
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
    return 0;
}

static int dpx_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;

    if (AV_RN32(b) == AV_RN32("SDPX") || AV_RN32(b) == AV_RN32("XPDS"))
        return AVPROBE_SCORE_EXTENSION + 1;
    return 0;
}

static int exr_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;

    if (AV_RL32(b) == 20000630)
        return AVPROBE_SCORE_EXTENSION + 1;
    return 0;
}

C
Carl Eugen Hoyos 已提交
610 611 612 613 614 615 616 617 618 619
static int j2k_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;

    if (AV_RB64(b) == 0x0000000c6a502020 ||
        AV_RB32(b) == 0xff4fff51)
        return AVPROBE_SCORE_EXTENSION + 1;
    return 0;
}

C
Carl Eugen Hoyos 已提交
620 621 622 623 624 625 626 627 628
static int jpegls_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;

    if (AV_RB32(b) == 0xffd8fff7)
         return AVPROBE_SCORE_EXTENSION + 1;
    return 0;
}

629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
static int pictor_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;

    if (AV_RL16(b) == 0x1234)
        return AVPROBE_SCORE_EXTENSION / 4;
    return 0;
}

static int png_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;

    if (AV_RB64(b) == 0x89504e470d0a1a0a)
        return AVPROBE_SCORE_MAX - 1;
    return 0;
}

static int sgi_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;

    if (AV_RB16(b) == 474 &&
        (b[2] & ~1) == 0 &&
        (b[3] & ~3) == 0 && b[3] &&
        (AV_RB16(b + 4) & ~7) == 0 && AV_RB16(b + 4))
        return AVPROBE_SCORE_EXTENSION + 1;
    return 0;
}

static int sunrast_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;

    if (AV_RB32(b) == 0x59a66a95)
        return AVPROBE_SCORE_EXTENSION + 1;
    return 0;
}

static int tiff_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;

672 673
    if (AV_RB32(b) == 0x49492a00 ||
        AV_RB32(b) == 0x4D4D002a)
674 675 676 677
        return AVPROBE_SCORE_EXTENSION + 1;
    return 0;
}

C
Carl Eugen Hoyos 已提交
678 679 680 681 682 683 684 685 686 687
static int webp_probe(AVProbeData *p)
{
    const uint8_t *b = p->buf;

    if (AV_RB32(b)     == 0x52494646 &&
        AV_RB32(b + 8) == 0x57454250)
        return AVPROBE_SCORE_MAX - 1;
    return 0;
}

688 689 690 691
#define IMAGEAUTO_DEMUXER(imgname, codecid)\
static const AVClass imgname ## _class = {\
    .class_name = AV_STRINGIFY(imgname) " demuxer",\
    .item_name  = av_default_item_name,\
692
    .option     = ff_img_options,\
693 694 695 696
    .version    = LIBAVUTIL_VERSION_INT,\
};\
AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\
    .name           = AV_STRINGIFY(imgname) "_pipe",\
697
    .long_name      = NULL_IF_CONFIG_SMALL("piped " AV_STRINGIFY(imgname) " sequence"),\
698 699 700 701 702 703 704 705 706 707 708
    .priv_data_size = sizeof(VideoDemuxData),\
    .read_probe     = imgname ## _probe,\
    .read_header    = ff_img_read_header,\
    .read_packet    = ff_img_read_packet,\
    .priv_class     = & imgname ## _class,\
    .raw_codec_id   = codecid,\
};

IMAGEAUTO_DEMUXER(bmp,     AV_CODEC_ID_BMP)
IMAGEAUTO_DEMUXER(dpx,     AV_CODEC_ID_DPX)
IMAGEAUTO_DEMUXER(exr,     AV_CODEC_ID_EXR)
C
Carl Eugen Hoyos 已提交
709
IMAGEAUTO_DEMUXER(j2k,     AV_CODEC_ID_JPEG2000)
C
Carl Eugen Hoyos 已提交
710
IMAGEAUTO_DEMUXER(jpegls,  AV_CODEC_ID_JPEGLS)
711 712 713 714 715
IMAGEAUTO_DEMUXER(pictor,  AV_CODEC_ID_PICTOR)
IMAGEAUTO_DEMUXER(png,     AV_CODEC_ID_PNG)
IMAGEAUTO_DEMUXER(sgi,     AV_CODEC_ID_SGI)
IMAGEAUTO_DEMUXER(sunrast, AV_CODEC_ID_SUNRAST)
IMAGEAUTO_DEMUXER(tiff,    AV_CODEC_ID_TIFF)
C
Carl Eugen Hoyos 已提交
716
IMAGEAUTO_DEMUXER(webp,    AV_CODEC_ID_WEBP)