GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/lzf.c Lines: 24 35 68.6 %
Date: 2019-11-22 03:34:36 Branches: 9 16 56.2 %

Line Branch Exec Source
1
/*
2
 * lzf decompression algorithm
3
 * Copyright (c) 2015 Luca Barbato
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
 * lzf decompression
25
 *
26
 * LZF is a fast compression/decompression algorithm that takes very little
27
 * code space and working memory, ideal for real-time and block compression.
28
 *
29
 * https://en.wikibooks.org/wiki/Data_Compression/Dictionary_compression#LZF
30
 */
31
32
#include "libavutil/mem.h"
33
34
#include "bytestream.h"
35
#include "lzf.h"
36
37
#define LZF_LITERAL_MAX (1 << 5)
38
#define LZF_LONG_BACKREF 7 + 2
39
40
4
int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, int64_t *size)
41
{
42
4
    int ret     = 0;
43
4
    uint8_t *p  = *buf;
44
4
    int64_t len = 0;
45
46
85160
    while (bytestream2_get_bytes_left(gb) > 2) {
47
85156
        uint8_t s = bytestream2_get_byte(gb);
48
49
85156
        if (s < LZF_LITERAL_MAX) {
50
18284
            s++;
51
18284
            if (s > *size - len) {
52
                *size += *size /2;
53
                ret = av_reallocp(buf, *size);
54
                if (ret < 0)
55
                    return ret;
56
                p = *buf + len;
57
            }
58
59
18284
            bytestream2_get_buffer(gb, p, s);
60
18284
            p   += s;
61
18284
            len += s;
62
        } else {
63
66872
            int l   = 2 + (s >> 5);
64
66872
            int off = ((s & 0x1f) << 8) + 1;
65
66
66872
            if (l == LZF_LONG_BACKREF)
67
39906
                l += bytestream2_get_byte(gb);
68
69
66872
            off += bytestream2_get_byte(gb);
70
71
66872
            if (off > len)
72
                return AVERROR_INVALIDDATA;
73
74
66872
            if (l > *size - len) {
75
                *size += *size / 2;
76
                ret = av_reallocp(buf, *size);
77
                if (ret < 0)
78
                    return ret;
79
                p = *buf + len;
80
            }
81
82
66872
            av_memcpy_backptr(p, off, l);
83
84
66872
            p   += l;
85
66872
            len += l;
86
        }
87
    }
88
89
4
    *size = len;
90
91
4
    return 0;
92
}