img2dec.c 21.8 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 32
#include "avformat.h"
#include "internal.h"
33
#include "img2.h"
34

35
#if HAVE_GLOB
36 37 38 39 40 41 42 43 44 45
/* 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 */
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

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 已提交
63
    for (i = 0; i < FF_ARRAY_ELEMS(sizes); i++) {
64
        if ((sizes[i][0] * sizes[i][1]) == size) {
D
Diego Biurrun 已提交
65
            *width_ptr  = sizes[i][0];
66 67 68 69
            *height_ptr = sizes[i][1];
            return 0;
        }
    }
D
Diego Biurrun 已提交
70

71 72 73
    return -1;
}

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

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

95 96 97 98 99 100 101 102 103
/**
 * 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
 */
104
static int find_image_range(int *pfirst_index, int *plast_index,
105
                            const char *path, int start_index, int start_index_range)
106 107 108 109 110
{
    char buf[1024];
    int range, last_index, range1, first_index;

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

    /* find the last image */
    last_index = first_index;
D
Diego Biurrun 已提交
127
    for (;;) {
128
        range = 0;
D
Diego Biurrun 已提交
129
        for (;;) {
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
            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 已提交
150
    *plast_index  = last_index;
151
    return 0;
D
Diego Biurrun 已提交
152 153

fail:
154 155 156
    return -1;
}

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

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

    s1->ctx_flags |= AVFMTCTX_NOHEADER;

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

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

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

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

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

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

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

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

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

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

            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 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
            avio_seek(s1->pb, -8, SEEK_CUR);

            pd.buf = probe_buffer;
            pd.buf_size = 8;
            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;
                }
            }
339
            av_free(probe_buffer);
340 341 342
        }
        if (st->codec->codec_id == AV_CODEC_ID_NONE)
            st->codec->codec_id = ff_guess_image2_codec(s->path);
343 344
        if (st->codec->codec_id == AV_CODEC_ID_LJPEG)
            st->codec->codec_id = AV_CODEC_ID_MJPEG;
345 346
        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;
347
    }
D
Diego Biurrun 已提交
348 349
    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
        pix_fmt != AV_PIX_FMT_NONE)
350 351 352 353 354
        st->codec->pix_fmt = pix_fmt;

    return 0;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

516 517
    { "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 },
518
    { "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 },
519
    { "video_size",   "set video size",                      OFFSET(width),        AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0,   DEC },
520
    { "frame_size",   "force frame size in bytes",           OFFSET(frame_size),   AV_OPT_TYPE_INT,    {.i64 = 0   }, 0, INT_MAX, DEC },
521 522
    { "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 已提交
523 524
    { "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" },
525 526 527 528 529 530 531 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,
    .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 已提交
539
    .read_probe     = img_read_probe,
540 541
    .read_header    = ff_img_read_header,
    .read_packet    = ff_img_read_packet,
542
    .read_close     = img_read_close,
P
Paul B Mahol 已提交
543
    .read_seek      = img_read_seek,
544 545 546 547 548 549 550 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,
    .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),
559 560
    .read_header    = ff_img_read_header,
    .read_packet    = ff_img_read_packet,
561 562 563
    .priv_class     = &img2pipe_class,
};
#endif
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595

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

    if (AV_RB16(b) == 0x424d)
        if (!AV_RN32(b + 6)) {
            return AVPROBE_SCORE_EXTENSION + 1;
        } else {
            return AVPROBE_SCORE_EXTENSION / 4;
        }
    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 已提交
596 597 598 599 600 601 602 603 604 605
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;
}

606 607 608 609 610 611 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 669 670 671 672 673 674 675
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",\
    .priv_data_size = sizeof(VideoDemuxData),\
    .read_probe     = imgname ## _probe,\
    .read_header    = ff_img_read_header,\
    .read_packet    = ff_img_read_packet,\
    .read_close     = img_read_close,\
    .read_seek      = img_read_seek,\
    .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 已提交
676
IMAGEAUTO_DEMUXER(j2k,     AV_CODEC_ID_JPEG2000)
677 678 679 680 681
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)