Coverage Report

Created: 2026-01-16 07:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavcodec/wbmpdec.c
Line
Count
Source
1
/*
2
 * WBMP (Wireless Application Protocol Bitmap) image
3
 *
4
 * This file is part of FFmpeg.
5
 *
6
 * FFmpeg is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * FFmpeg is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with FFmpeg; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
21
#include "avcodec.h"
22
#include "bytestream.h"
23
#include "codec_internal.h"
24
#include "decode.h"
25
#include "thread.h"
26
27
static unsigned int getv(GetByteContext * gb)
28
466k
{
29
466k
    int i;
30
466k
    unsigned int v = 0;
31
32
654k
    do {
33
654k
        i = bytestream2_get_byte(gb);
34
654k
        v = (v << 7) | (i & 0x7F);
35
654k
    } while (i & 0x80);
36
466k
    return v;
37
466k
}
38
39
static void readbits(uint8_t * dst, int width, int height, int linesize, const uint8_t * src, int size)
40
91.1k
{
41
91.1k
    int wpad = (width + 7) / 8;
42
307k
    for (int j = 0; j < height && size > 0; j++) {
43
216k
        memcpy(dst, src, FFMIN(wpad, size));
44
216k
        src += wpad;
45
216k
        size -= wpad;
46
216k
        dst += linesize;
47
216k
    }
48
91.1k
}
49
50
static int wbmp_decode_frame(AVCodecContext *avctx, AVFrame *p,
51
                            int *got_frame, AVPacket *avpkt)
52
268k
{
53
268k
    const uint8_t *buf = avpkt->data;
54
268k
    int buf_size = avpkt->size, width, height, ret;
55
268k
    GetByteContext gb;
56
57
268k
    bytestream2_init(&gb, buf, buf_size);
58
59
268k
    if (getv(&gb))
60
169k
        return AVERROR_INVALIDDATA;
61
99.2k
    bytestream2_skip(&gb, 1);
62
99.2k
    width = getv(&gb);
63
99.2k
    height = getv(&gb);
64
65
99.2k
    if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
66
5.93k
        return ret;
67
68
93.3k
    avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
69
93.3k
    if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
70
887
        return ret;
71
72
92.4k
    if (p->linesize[0] == (width + 7) / 8)
73
1.22k
        bytestream2_get_buffer(&gb, p->data[0], height * ((width + 7) / 8));
74
91.1k
    else
75
91.1k
        readbits(p->data[0], width, height, p->linesize[0],
76
91.1k
                 gb.buffer, bytestream2_get_bytes_left(&gb));
77
78
92.4k
    *got_frame   = 1;
79
80
92.4k
    return buf_size;
81
93.3k
}
82
83
const FFCodec ff_wbmp_decoder = {
84
    .p.name         = "wbmp",
85
    CODEC_LONG_NAME("WBMP (Wireless Application Protocol Bitmap) image"),
86
    .p.type         = AVMEDIA_TYPE_VIDEO,
87
    .p.id           = AV_CODEC_ID_WBMP,
88
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
89
    FF_CODEC_DECODE_CB(wbmp_decode_frame),
90
};