Coverage Report

Created: 2024-09-06 07:53

/src/ffmpeg/libavcodec/mvha.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * MidiVid Archive codec
3
 *
4
 * Copyright (c) 2019 Paul B Mahol
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * 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
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
23
#define CACHED_BITSTREAM_READER !ARCH_X86_32
24
#include "libavutil/intreadwrite.h"
25
26
#include "avcodec.h"
27
#include "codec_internal.h"
28
#include "decode.h"
29
#include "get_bits.h"
30
#include "lossless_videodsp.h"
31
#include "zlib_wrapper.h"
32
33
#include <zlib.h>
34
35
typedef struct MVHAContext {
36
    GetBitContext     gb;
37
    int nb_symbols;
38
39
    uint8_t           symb[256];
40
    uint32_t          prob[256];
41
    VLC               vlc;
42
43
    FFZStream         zstream;
44
    LLVidDSPContext   llviddsp;
45
} MVHAContext;
46
47
typedef struct Node {
48
    int16_t  sym;
49
    int16_t  n0;
50
    int16_t  l, r;
51
    uint32_t count;
52
} Node;
53
54
static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat,
55
                           Node *nodes, int node,
56
                           uint32_t pfx, int pl, int *pos)
57
431k
{
58
431k
    int s;
59
60
431k
    s = nodes[node].sym;
61
431k
    if (s != -1) {
62
241k
        bits[*pos] = (~pfx) & ((1ULL << FFMAX(pl, 1)) - 1);
63
241k
        lens[*pos] = FFMAX(pl, 1);
64
241k
        xlat[*pos] = s + (pl == 0);
65
241k
        (*pos)++;
66
241k
    } else {
67
190k
        pfx <<= 1;
68
190k
        pl++;
69
190k
        get_tree_codes(bits, lens, xlat, nodes, nodes[node].l, pfx, pl,
70
190k
                       pos);
71
190k
        pfx |= 1;
72
190k
        get_tree_codes(bits, lens, xlat, nodes, nodes[node].r, pfx, pl,
73
190k
                       pos);
74
190k
    }
75
431k
}
76
77
static int build_vlc(AVCodecContext *avctx, VLC *vlc)
78
51.2k
{
79
51.2k
    MVHAContext *s = avctx->priv_data;
80
51.2k
    Node nodes[512];
81
51.2k
    uint32_t bits[256];
82
51.2k
    int16_t lens[256];
83
51.2k
    uint8_t xlat[256];
84
51.2k
    int cur_node, i, j, pos = 0;
85
86
51.2k
    ff_vlc_free(vlc);
87
88
292k
    for (i = 0; i < s->nb_symbols; i++) {
89
241k
        nodes[i].count = s->prob[i];
90
241k
        nodes[i].sym   = s->symb[i];
91
241k
        nodes[i].n0    = -2;
92
241k
        nodes[i].l     = i;
93
241k
        nodes[i].r     = i;
94
241k
    }
95
96
51.2k
    cur_node = s->nb_symbols;
97
51.2k
    j = 0;
98
81.6k
    do {
99
271k
        for (i = 0; ; i++) {
100
271k
            int new_node = j;
101
271k
            int first_node = cur_node;
102
271k
            int second_node = cur_node;
103
271k
            unsigned nd, st;
104
105
271k
            nodes[cur_node].count = -1;
106
107
30.4M
            do {
108
30.4M
                int val = nodes[new_node].count;
109
30.4M
                if (val && (val < nodes[first_node].count)) {
110
1.08M
                    if (val >= nodes[second_node].count) {
111
452k
                        first_node = new_node;
112
633k
                    } else {
113
633k
                        first_node = second_node;
114
633k
                        second_node = new_node;
115
633k
                    }
116
1.08M
                }
117
30.4M
                new_node += 1;
118
30.4M
            } while (new_node != cur_node);
119
120
271k
            if (first_node == cur_node)
121
81.6k
                break;
122
123
190k
            nd = nodes[second_node].count;
124
190k
            st = nodes[first_node].count;
125
190k
            nodes[second_node].count = 0;
126
190k
            nodes[first_node].count  = 0;
127
190k
            if (nd >= UINT32_MAX - st) {
128
0
                av_log(avctx, AV_LOG_ERROR, "count overflow\n");
129
0
                return AVERROR_INVALIDDATA;
130
0
            }
131
190k
            nodes[cur_node].count = nd + st;
132
190k
            nodes[cur_node].sym = -1;
133
190k
            nodes[cur_node].n0 = cur_node;
134
190k
            nodes[cur_node].l = first_node;
135
190k
            nodes[cur_node].r = second_node;
136
190k
            cur_node++;
137
190k
        }
138
81.6k
        j++;
139
81.6k
    } while (cur_node - s->nb_symbols == j);
140
141
51.2k
    get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos);
142
143
51.2k
    return ff_vlc_init_sparse(vlc, 12, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0);
144
51.2k
}
145
146
static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
147
                        int *got_frame, AVPacket *avpkt)
148
115k
{
149
115k
    MVHAContext *s = avctx->priv_data;
150
115k
    uint32_t type, size;
151
115k
    int ret;
152
153
115k
    if (avpkt->size <= 8)
154
5.51k
        return AVERROR_INVALIDDATA;
155
156
110k
    type = AV_RB32(avpkt->data);
157
110k
    size = AV_RL32(avpkt->data + 4);
158
159
110k
    if (size < 1 || size >= avpkt->size)
160
12.2k
        return AVERROR_INVALIDDATA;
161
162
98.2k
    if (type == MKTAG('L','Z','Y','V')) {
163
41.1k
        z_stream *const zstream = &s->zstream.zstream;
164
41.1k
        ret = inflateReset(zstream);
165
41.1k
        if (ret != Z_OK) {
166
0
            av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", ret);
167
0
            return AVERROR_EXTERNAL;
168
0
        }
169
170
41.1k
        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
171
1.63k
            return ret;
172
173
39.5k
        zstream->next_in  = avpkt->data + 8;
174
39.5k
        zstream->avail_in = avpkt->size - 8;
175
176
65.4k
        for (int p = 0; p < 3; p++) {
177
3.02M
            for (int y = 0; y < avctx->height; y++) {
178
2.99M
                zstream->next_out  = frame->data[p] + (avctx->height - y - 1) * frame->linesize[p];
179
2.99M
                zstream->avail_out = avctx->width >> (p > 0);
180
181
2.99M
                ret = inflate(zstream, Z_SYNC_FLUSH);
182
2.99M
                if (ret != Z_OK && ret != Z_STREAM_END) {
183
35.4k
                    av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", ret);
184
35.4k
                    return AVERROR_EXTERNAL;
185
35.4k
                }
186
2.96M
                if (zstream->avail_out > 0)
187
1.87M
                    memset(zstream->next_out, 0, zstream->avail_out);
188
2.96M
            }
189
61.3k
        }
190
57.0k
    } else if (type == MKTAG('H','U','F','Y')) {
191
55.4k
        GetBitContext *gb = &s->gb;
192
55.4k
        int first_symbol, symbol;
193
194
55.4k
        ret = init_get_bits8(gb, avpkt->data + 8, avpkt->size - 8);
195
55.4k
        if (ret < 0)
196
0
            return ret;
197
198
55.4k
        skip_bits(gb, 24);
199
200
55.4k
        first_symbol = get_bits(gb, 8);
201
55.4k
        s->nb_symbols = get_bits(gb, 8) + 1;
202
203
55.4k
        symbol = first_symbol;
204
548k
        for (int i = 0; i < s->nb_symbols; symbol++) {
205
495k
            int prob;
206
207
495k
            if (get_bits_left(gb) < 4)
208
2.05k
                return AVERROR_INVALIDDATA;
209
210
493k
            if (get_bits1(gb)) {
211
135k
                prob = get_bits(gb, 12);
212
357k
            } else {
213
357k
                prob = get_bits(gb, 3);
214
357k
            }
215
216
493k
            if (prob) {
217
344k
                s->symb[i] = symbol;
218
344k
                s->prob[i] = prob;
219
344k
                i++;
220
344k
            }
221
493k
        }
222
223
53.4k
        if (get_bits_left(gb) < avctx->height * avctx->width)
224
2.19k
            return AVERROR_INVALIDDATA;
225
226
51.2k
        ret = build_vlc(avctx, &s->vlc);
227
51.2k
        if (ret < 0)
228
0
            return ret;
229
230
51.2k
        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
231
10.1k
            return ret;
232
233
160k
        for (int p = 0; p < 3; p++) {
234
121k
            int width = avctx->width >> (p > 0);
235
121k
            ptrdiff_t stride = frame->linesize[p];
236
121k
            uint8_t *dst;
237
238
121k
            dst = frame->data[p] + (avctx->height - 1) * frame->linesize[p];
239
316k
            for (int y = 0; y < avctx->height; y++) {
240
196k
                if (get_bits_left(gb) < width)
241
1.05k
                    return AVERROR_INVALIDDATA;
242
2.60M
                for (int x = 0; x < width; x++) {
243
2.40M
                    int v = get_vlc2(gb, s->vlc.table, s->vlc.bits, 3);
244
245
2.40M
                    if (v < 0)
246
503
                        return AVERROR_INVALIDDATA;
247
248
2.40M
                    dst[x] = v;
249
2.40M
                }
250
195k
                dst -= stride;
251
195k
            }
252
121k
        }
253
41.0k
    } else {
254
1.61k
        return AVERROR_INVALIDDATA;
255
1.61k
    }
256
257
174k
    for (int p = 0; p < 3; p++) {
258
130k
        int left, lefttop;
259
130k
        int width = avctx->width >> (p > 0);
260
130k
        ptrdiff_t stride = frame->linesize[p];
261
130k
        uint8_t *dst;
262
263
130k
        dst = frame->data[p] + (avctx->height - 1) * frame->linesize[p];
264
130k
        s->llviddsp.add_left_pred(dst, dst, width, 0);
265
130k
        if (avctx->height > 1) {
266
16.0k
            dst -= stride;
267
16.0k
            lefttop = left = dst[0];
268
2.10M
            for (int y = 1; y < avctx->height; y++) {
269
2.08M
                s->llviddsp.add_median_pred(dst, dst + stride, dst, width, &left, &lefttop);
270
2.08M
                lefttop = left = dst[0];
271
2.08M
                dst -= stride;
272
2.08M
            }
273
16.0k
        }
274
130k
    }
275
276
43.6k
    *got_frame = 1;
277
278
43.6k
    return avpkt->size;
279
98.2k
}
280
281
static av_cold int decode_init(AVCodecContext *avctx)
282
2.10k
{
283
2.10k
    MVHAContext *s = avctx->priv_data;
284
285
2.10k
    avctx->pix_fmt = AV_PIX_FMT_YUV422P;
286
287
2.10k
    ff_llviddsp_init(&s->llviddsp);
288
289
2.10k
    return ff_inflate_init(&s->zstream, avctx);
290
2.10k
}
291
292
static av_cold int decode_close(AVCodecContext *avctx)
293
2.10k
{
294
2.10k
    MVHAContext *s = avctx->priv_data;
295
296
2.10k
    ff_inflate_end(&s->zstream);
297
2.10k
    ff_vlc_free(&s->vlc);
298
299
2.10k
    return 0;
300
2.10k
}
301
302
const FFCodec ff_mvha_decoder = {
303
    .p.name           = "mvha",
304
    CODEC_LONG_NAME("MidiVid Archive Codec"),
305
    .p.type           = AVMEDIA_TYPE_VIDEO,
306
    .p.id             = AV_CODEC_ID_MVHA,
307
    .priv_data_size   = sizeof(MVHAContext),
308
    .init             = decode_init,
309
    .close            = decode_close,
310
    FF_CODEC_DECODE_CB(decode_frame),
311
    .p.capabilities   = AV_CODEC_CAP_DR1,
312
    .caps_internal    = FF_CODEC_CAP_INIT_CLEANUP,
313
};