img2dec.c 21.9 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
        else if (av_match_ext(p->filename, "raw") || av_match_ext(p->filename, "gif"))
166
            return 5;
167
        else
168
            return AVPROBE_SCORE_EXTENSION;
169 170 171 172
    }
    return 0;
}

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

    s1->ctx_flags |= AVFMTCTX_NOHEADER;

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

D
Diego Biurrun 已提交
187 188 189 190
    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);
191 192 193 194 195
        return AVERROR(EINVAL);
    }

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

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

206 207 208 209 210 211 212
    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)
213
        avpriv_set_pts_info(st, 64, 1, 1);
A
Andrey Utkin 已提交
214
    else
215
        avpriv_set_pts_info(st, 64, s->framerate.den, s->framerate.num);
216

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

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

229 230 231
            av_log(s1, AV_LOG_WARNING, "Pattern type 'glob_sequence' is deprecated: "
                   "use pattern_type 'glob' instead\n");
#if HAVE_GLOB
232 233 234 235 236 237 238 239 240 241 242 243 244 245
            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);

246
            gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate);
247 248 249 250 251 252
            if (gerr != 0) {
                return AVERROR(ENOENT);
            }
            first_index = 0;
            last_index = s->globstate.gl_pathc - 1;
#endif
253 254 255
        }
        }
        if ((s->pattern_type == PT_GLOB_SEQUENCE && !s->use_glob) || s->pattern_type == PT_SEQUENCE) {
256
            if (find_image_range(&first_index, &last_index, s->path,
257
                                 s->start_number, s->start_number_range) < 0) {
258
                av_log(s1, AV_LOG_ERROR,
259
                       "Could find no file with path '%s' and index in the range %d-%d\n",
260
                       s->path, s->start_number, s->start_number + s->start_number_range - 1);
261
                return AVERROR(ENOENT);
262
            }
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
        } 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);
283
        }
D
Diego Biurrun 已提交
284 285
        s->img_first  = first_index;
        s->img_last   = last_index;
286 287
        s->img_number = first_index;
        /* compute duration */
288 289 290 291
        if (!s->ts_from_file) {
            st->start_time = 0;
            st->duration   = last_index - first_index + 1;
        }
292 293
    }

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

            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);
322 323

            pd.buf = probe_buffer;
324
            pd.buf_size = probe_buffer_size;
325 326 327 328 329 330 331 332 333 334 335 336 337
            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;
                }
            }
338
            ffio_rewind_with_probe_data(s1->pb, &probe_buffer, probe_buffer_size);
339 340 341
        }
        if (st->codec->codec_id == AV_CODEC_ID_NONE)
            st->codec->codec_id = ff_guess_image2_codec(s->path);
342 343
        if (st->codec->codec_id == AV_CODEC_ID_LJPEG)
            st->codec->codec_id = AV_CODEC_ID_MJPEG;
344 345
        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;
346
    }
D
Diego Biurrun 已提交
347 348
    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
        pix_fmt != AV_PIX_FMT_NONE)
349 350 351 352 353
        st->codec->pix_fmt = pix_fmt;

    return 0;
}

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

    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;
371 372 373 374 375 376
        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 已提交
377 378
                                  s->path,
                                  s->img_number) < 0 && s->img_number > 1)
379
            return AVERROR(EIO);
380
        }
D
Diego Biurrun 已提交
381
        for (i = 0; i < 3; i++) {
382 383
            if (avio_open2(&f[i], filename, AVIO_FLAG_READ,
                           &s1->interrupt_callback, NULL) < 0) {
D
Diego Biurrun 已提交
384
                if (i >= 1)
385
                    break;
D
Diego Biurrun 已提交
386 387
                av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n",
                       filename);
388 389
                return AVERROR(EIO);
            }
D
Diego Biurrun 已提交
390
            size[i] = avio_size(f[i]);
391

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

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

404
            ret = avio_read(f[0], header, PROBE_BUF_MIN);
405 406
            if (ret < 0)
                return ret;
407
            memset(header + ret, 0, sizeof(header) - ret);
408 409 410 411 412 413 414 415 416 417
            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 已提交
418
        if (codec->codec_id == AV_CODEC_ID_RAWVIDEO && !codec->width)
419 420 421
            infer_size(&codec->width, &codec->height, size[0]);
    } else {
        f[0] = s1->pb;
422
        if (url_feof(f[0]))
423
            return AVERROR(EIO);
424 425
        if (s->frame_size > 0) {
            size[0] = s->frame_size;
426 427
        } else if (!s1->streams[0]->parser) {
            size[0] = avio_size(s1->pb);
428
        } else {
429
            size[0] = 4096;
430
        }
431 432
    }

433 434
    if (av_new_packet(pkt, size[0] + size[1] + size[2]) < 0)
        return AVERROR(ENOMEM);
435
    pkt->stream_index = 0;
D
Diego Biurrun 已提交
436
    pkt->flags       |= AV_PKT_FLAG_KEY;
A
Andrey Utkin 已提交
437 438 439 440 441
    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;
442 443 444 445
#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
446
        av_add_index_entry(s1->streams[0], s->img_number, pkt->pts, 0, 0, AVINDEX_KEYFRAME);
A
Andrey Utkin 已提交
447
    } else if (!s->is_pipe) {
448
        pkt->pts      = s->pts;
A
Andrey Utkin 已提交
449
    }
450

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

D
Diego Biurrun 已提交
462
    if (ret[0] <= 0 || ret[1] < 0 || ret[2] < 0) {
463 464 465 466 467
        av_free_packet(pkt);
        return AVERROR(EIO); /* signal EOF */
    } else {
        s->img_count++;
        s->img_number++;
468
        s->pts++;
469 470 471 472
        return 0;
    }
}

473
static int img_read_close(struct AVFormatContext* s1)
474 475 476 477 478 479 480 481 482 483
{
    VideoDemuxData *s = s1->priv_data;
#if HAVE_GLOB
    if (s->use_glob) {
        globfree(&s->globstate);
    }
#endif
    return 0;
}

P
Paul B Mahol 已提交
484 485 486
static int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
{
    VideoDemuxData *s1 = s->priv_data;
487 488 489 490 491 492 493 494 495
    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 已提交
496

497
    if (timestamp < 0 || !s1->loop && timestamp > s1->img_last - s1->img_first)
P
Paul B Mahol 已提交
498
        return -1;
499 500
    s1->img_number = timestamp%(s1->img_last - s1->img_first + 1) + s1->img_first;
    s1->pts = timestamp;
P
Paul B Mahol 已提交
501 502 503
    return 0;
}

504 505 506
#define OFFSET(x) offsetof(VideoDemuxData, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
static const AVOption options[] = {
507
    { "framerate",    "set the video framerate",             OFFSET(framerate),    AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0,   DEC },
508
    { "loop",         "force loop over input file sequence", OFFSET(loop),         AV_OPT_TYPE_INT,    {.i64 = 0   }, 0, 1,       DEC },
509

510
    { "pattern_type", "set pattern type",                    OFFSET(pattern_type), AV_OPT_TYPE_INT,    {.i64=PT_GLOB_SEQUENCE}, 0,       INT_MAX, DEC, "pattern_type"},
511 512 513
    { "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" },
514

515 516
    { "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 },
517
    { "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 },
518
    { "video_size",   "set video size",                      OFFSET(width),        AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0,   DEC },
519
    { "frame_size",   "force frame size in bytes",           OFFSET(frame_size),   AV_OPT_TYPE_INT,    {.i64 = 0   }, 0, INT_MAX, DEC },
520 521
    { "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 已提交
522 523
    { "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" },
524 525 526 527 528 529 530 531 532 533 534 535 536 537
    { NULL },
};

#if CONFIG_IMAGE2_DEMUXER
static const AVClass img2_class = {
    .class_name = "image2 demuxer",
    .item_name  = av_default_item_name,
    .option     = options,
    .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 已提交
538
    .read_probe     = img_read_probe,
539 540
    .read_header    = ff_img_read_header,
    .read_packet    = ff_img_read_packet,
541
    .read_close     = img_read_close,
P
Paul B Mahol 已提交
542
    .read_seek      = img_read_seek,
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
    .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,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};
AVInputFormat ff_image2pipe_demuxer = {
    .name           = "image2pipe",
    .long_name      = NULL_IF_CONFIG_SMALL("piped image2 sequence"),
    .priv_data_size = sizeof(VideoDemuxData),
558 559
    .read_header    = ff_img_read_header,
    .read_packet    = ff_img_read_packet,
560 561 562
    .priv_class     = &img2pipe_class,
};
#endif
563 564 565 566

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

569 570 571 572 573 574 575 576 577 578 579 580
    if (AV_RB16(b) != 0x424d)
        return 0;

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

    if (!AV_RN32(b + 6)) {
        return AVPROBE_SCORE_EXTENSION + 1;
    } else {
        return AVPROBE_SCORE_EXTENSION / 4;
    }
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
    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 已提交
602 603 604 605 606 607 608 609 610 611
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;
}

612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 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
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;

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

#define IMAGEAUTO_DEMUXER(imgname, codecid)\
static const AVClass imgname ## _class = {\
    .class_name = AV_STRINGIFY(imgname) " demuxer",\
    .item_name  = av_default_item_name,\
    .option     = options,\
    .version    = LIBAVUTIL_VERSION_INT,\
};\
AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\
    .name           = AV_STRINGIFY(imgname) "_pipe",\
669
    .long_name      = NULL_IF_CONFIG_SMALL("piped " AV_STRINGIFY(imgname) " sequence"),\
670 671 672 673 674 675 676 677 678 679 680
    .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 已提交
681
IMAGEAUTO_DEMUXER(j2k,     AV_CODEC_ID_JPEG2000)
682 683 684 685 686
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)