GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/mjpegbdec.c Lines: 65 78 83.3 %
Date: 2019-11-22 03:34:36 Branches: 18 38 47.4 %

Line Branch Exec Source
1
/*
2
 * Apple MJPEG-B decoder
3
 * Copyright (c) 2002 Alex Beregszaszi
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
/**
23
 * @file
24
 * Apple MJPEG-B decoder.
25
 */
26
27
#include <inttypes.h>
28
29
#include "avcodec.h"
30
#include "internal.h"
31
#include "mjpeg.h"
32
#include "mjpegdec.h"
33
34
132
static uint32_t read_offs(AVCodecContext *avctx, GetBitContext *gb, uint32_t size, const char *err_msg){
35
132
    uint32_t offs= get_bits_long(gb, 32);
36
132
    if(offs >= size){
37
        av_log(avctx, AV_LOG_WARNING, err_msg, offs, size);
38
        return 0;
39
    }
40
132
    return offs;
41
}
42
43
11
static int mjpegb_decode_frame(AVCodecContext *avctx,
44
                              void *data, int *got_frame,
45
                              AVPacket *avpkt)
46
{
47
11
    const uint8_t *buf = avpkt->data;
48
11
    int buf_size = avpkt->size;
49
11
    MJpegDecodeContext *s = avctx->priv_data;
50
    const uint8_t *buf_end, *buf_ptr;
51
    GetBitContext hgb; /* for the header */
52
    uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs;
53
    uint32_t field_size, sod_offs;
54
    int ret;
55
56
11
    buf_ptr = buf;
57
11
    buf_end = buf + buf_size;
58
11
    s->got_picture = 0;
59
11
    s->adobe_transform = -1;
60
61
22
read_header:
62
    /* reset on every SOI */
63
22
    s->restart_interval = 0;
64
22
    s->restart_count = 0;
65
22
    s->mjpb_skiptosod = 0;
66
67
22
    if (buf_end - buf_ptr >= 1 << 28)
68
        return AVERROR_INVALIDDATA;
69
70
22
    init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8);
71
72
22
    skip_bits(&hgb, 32); /* reserved zeros */
73
74
22
    if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g')) {
75
        av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n");
76
        return AVERROR_INVALIDDATA;
77
    }
78
79
22
    field_size = get_bits_long(&hgb, 32); /* field size */
80
22
    av_log(avctx, AV_LOG_DEBUG, "field size: 0x%"PRIx32"\n", field_size);
81
22
    skip_bits(&hgb, 32); /* padded field size */
82
22
    second_field_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "second_field_offs is %d and size is %d\n");
83
22
    av_log(avctx, AV_LOG_DEBUG, "second field offs: 0x%"PRIx32"\n",
84
           second_field_offs);
85
86
22
    dqt_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dqt is %d and size is %d\n");
87
22
    av_log(avctx, AV_LOG_DEBUG, "dqt offs: 0x%"PRIx32"\n", dqt_offs);
88
22
    if (dqt_offs) {
89
22
        init_get_bits(&s->gb, buf_ptr+dqt_offs, (buf_end - (buf_ptr+dqt_offs))*8);
90
22
        s->start_code = DQT;
91
22
        ret = ff_mjpeg_decode_dqt(s);
92

22
        if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
93
            return ret;
94
    }
95
96
22
    dht_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dht is %d and size is %d\n");
97
22
    av_log(avctx, AV_LOG_DEBUG, "dht offs: 0x%"PRIx32"\n", dht_offs);
98
22
    if (dht_offs) {
99
22
        init_get_bits(&s->gb, buf_ptr+dht_offs, (buf_end - (buf_ptr+dht_offs))*8);
100
22
        s->start_code = DHT;
101
22
        ff_mjpeg_decode_dht(s);
102
    }
103
104
22
    sof_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size is %d\n");
105
22
    av_log(avctx, AV_LOG_DEBUG, "sof offs: 0x%"PRIx32"\n", sof_offs);
106
22
    if (sof_offs) {
107
22
        init_get_bits(&s->gb, buf_ptr+sof_offs, (buf_end - (buf_ptr+sof_offs))*8);
108
22
        s->start_code = SOF0;
109
22
        if ((ret = ff_mjpeg_decode_sof(s)) < 0)
110
            return ret;
111
    }
112
113
22
    sos_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sos is %d and size is %d\n");
114
22
    av_log(avctx, AV_LOG_DEBUG, "sos offs: 0x%"PRIx32"\n", sos_offs);
115
22
    sod_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size is %d\n");
116
22
    av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%"PRIx32"\n", sod_offs);
117
22
    if (sos_offs) {
118
22
        init_get_bits(&s->gb, buf_ptr + sos_offs,
119
22
                      8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs));
120
22
        s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16));
121
22
        s->start_code = SOS;
122
22
        ret = ff_mjpeg_decode_sos(s, NULL, 0, NULL);
123

22
        if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
124
            return ret;
125
    }
126
127
22
    if (s->interlaced) {
128
22
        s->bottom_field ^= 1;
129
        /* if not bottom field, do not output image yet */
130

22
        if (s->bottom_field != s->interlace_polarity && second_field_offs) {
131
11
            buf_ptr = buf + second_field_offs;
132
11
            goto read_header;
133
        }
134
    }
135
136
    //XXX FIXME factorize, this looks very similar to the EOI code
137
138
11
    if(!s->got_picture) {
139
        av_log(avctx, AV_LOG_WARNING, "no picture\n");
140
        return buf_size;
141
    }
142
143
11
    if ((ret = av_frame_ref(data, s->picture_ptr)) < 0)
144
        return ret;
145
11
    *got_frame = 1;
146
147

11
    if (!s->lossless && avctx->debug & FF_DEBUG_QP) {
148
        av_log(avctx, AV_LOG_DEBUG, "QP: %d\n",
149
               FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]));
150
    }
151
152
11
    return buf_size;
153
}
154
155
AVCodec ff_mjpegb_decoder = {
156
    .name           = "mjpegb",
157
    .long_name      = NULL_IF_CONFIG_SMALL("Apple MJPEG-B"),
158
    .type           = AVMEDIA_TYPE_VIDEO,
159
    .id             = AV_CODEC_ID_MJPEGB,
160
    .priv_data_size = sizeof(MJpegDecodeContext),
161
    .init           = ff_mjpeg_decode_init,
162
    .close          = ff_mjpeg_decode_end,
163
    .decode         = mjpegb_decode_frame,
164
    .capabilities   = AV_CODEC_CAP_DR1,
165
    .max_lowres     = 3,
166
    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
167
};