FFmpeg
Loading...
Searching...
No Matches
lzf.c
Go to the documentation of this file.
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 "defs.h"
36#include "lzf.h"
37
38#define LZF_LITERAL_MAX (1 << 5)
39#define LZF_LONG_BACKREF 7 + 2
40
41
42static inline int lzf_realloc(uint8_t **buf, size_t new_size, unsigned *allocated_size)
43{
44 void *ptr = av_fast_realloc(*buf, allocated_size, new_size);
45
46 if (!ptr) {
47 av_freep(buf); //probably not needed
48 return AVERROR(ENOMEM);
49 }
50 *buf = ptr;
51
52 return 0;
53}
54
55int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, size_t *size, unsigned *allocated_size)
56{
57 int ret = 0;
58 uint8_t *p = *buf;
59 int64_t len = 0;
60
61 while (bytestream2_get_bytes_left(gb) > 2) {
62 uint8_t s = bytestream2_get_byte(gb);
63
64 if (s < LZF_LITERAL_MAX) {
65 s++;
66 if (s + AV_INPUT_BUFFER_PADDING_SIZE > *allocated_size - len) {
67 ret = lzf_realloc(buf, len + s + AV_INPUT_BUFFER_PADDING_SIZE, allocated_size);
68 if (ret < 0)
69 return ret;
70 p = *buf + len;
71 }
72
73 int s2 = bytestream2_get_buffer(gb, p, s);
74 if (s2 != s)
76
77 p += s;
78 len += s;
79 } else {
80 int l = 2 + (s >> 5);
81 int off = ((s & 0x1f) << 8) + 1;
82
83 if (l == LZF_LONG_BACKREF)
84 l += bytestream2_get_byte(gb);
85
86 off += bytestream2_get_byte(gb);
87
88 if (off > len)
90
91 if (l + AV_INPUT_BUFFER_PADDING_SIZE > *allocated_size - len) {
92 ret = lzf_realloc(buf, len + l + AV_INPUT_BUFFER_PADDING_SIZE, allocated_size);
93 if (ret < 0)
94 return ret;
95 p = *buf + len;
96 }
97
98 av_memcpy_backptr(p, off, l);
99
100 p += l;
101 len += l;
102 }
103 }
104
105 if (*buf)
106 memset(*buf + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
107
108 *size = len;
109
110 return 0;
111}
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition bytestream.h:267
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition bytestream.h:158
#define s(width, name)
Definition cbs_vp9.c:198
long long int64_t
Definition coverity.c:34
Misc types and constants that do not belong anywhere else.
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:495
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
Overlapping memcpy() implementation.
Definition mem.c:445
#define LZF_LITERAL_MAX
Definition lzf.c:38
int ff_lzf_uncompress(GetByteContext *gb, uint8_t **buf, size_t *size, unsigned *allocated_size)
Decompress LZF data into *buf, reallocating it as needed.
Definition lzf.c:55
static int lzf_realloc(uint8_t **buf, size_t new_size, unsigned *allocated_size)
Definition lzf.c:42
#define LZF_LONG_BACKREF
Definition lzf.c:39
Memory handling functions.
#define av_freep(p)
int size
int len