Skip to content

Commit 08cd75e

Browse files
committed
libmatroska2: replace minilzo with libavutil decoder for lzo1x
This is a slightly simplified version pulling less code from libavutil.
1 parent 768e75d commit 08cd75e

File tree

16 files changed

+351
-7068
lines changed

16 files changed

+351
-7068
lines changed

libmatroska2/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ if (CONFIG_ZLIB)
6161
endif(CONFIG_ZLIB)
6262

6363
if (CONFIG_LZO1X)
64-
add_subdirectory("minilzo")
65-
target_link_libraries("matroska2" PRIVATE $<BUILD_INTERFACE:minilzo>)
64+
add_subdirectory("lavu_lzo")
65+
target_link_libraries("matroska2" PRIVATE $<BUILD_INTERFACE:lavu_lzo>)
6666
endif(CONFIG_LZO1X)
6767

6868
if (CONFIG_BZLIB)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# libavutil lzo decompressor library API
2+
3+
add_library("lavu_lzo" STATIC)
4+
set(MINILZO_GROUP_PUBLIC_HEADERS
5+
lzo.h
6+
)
7+
set(MINILZO_GROUP_SOURCES lzo.c)
8+
9+
target_sources("lavu_lzo" PRIVATE ${MINILZO_GROUP_SOURCES} ${MINILZO_GROUP_PUBLIC_HEADERS})
10+
target_include_directories("lavu_lzo" PUBLIC ".")
11+
set_target_properties("lavu_lzo" PROPERTIES
12+
PUBLIC_HEADER "${MINILZO_GROUP_PUBLIC_HEADERS}"
13+
)

libmatroska2/lavu_lzo/lzo.c

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
/*
2+
* LZO 1x decompression
3+
* Copyright (c) 2006 Reimar Doeffinger
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+
#include <limits.h>
23+
#include <stdint.h>
24+
#include <string.h>
25+
#include <assert.h>
26+
27+
#include "lzo.h"
28+
29+
#define av_assert0(x) assert(x)
30+
#define FFMAX(x, y) ( (x) > (y) ? (x) : (y))
31+
#define AV_COPY32U(d, s) memcpy(d, s, 4)
32+
#define AV_COPY16U(d, s) memcpy(d, s, 2)
33+
34+
static inline void av_memcpy_backptr(uint8_t *dst, size_t back, size_t cnt)
35+
{
36+
if (!back)
37+
return;
38+
39+
const uint8_t* src = &dst[-back];
40+
if (back == 1) {
41+
memset(dst, *src, cnt);
42+
}
43+
else {
44+
if (cnt >= 4) {
45+
AV_COPY16U(dst, src);
46+
AV_COPY16U(dst + 2, src + 2);
47+
src += 4;
48+
dst += 4;
49+
cnt -= 4;
50+
}
51+
if (cnt >= 8) {
52+
AV_COPY16U(dst, src);
53+
AV_COPY16U(dst + 2, src + 2);
54+
AV_COPY16U(dst + 4, src + 4);
55+
AV_COPY16U(dst + 6, src + 6);
56+
src += 8;
57+
dst += 8;
58+
cnt -= 8;
59+
}
60+
if (cnt > 0) {
61+
size_t blocklen = back;
62+
while (cnt > blocklen) {
63+
memcpy(dst, src, blocklen);
64+
dst += blocklen;
65+
cnt -= blocklen;
66+
blocklen <<= 1;
67+
}
68+
memcpy(dst, src, cnt);
69+
}
70+
}
71+
}
72+
73+
/// Define if we may write up to 12 bytes beyond the output buffer.
74+
#define OUTBUF_PADDED 1
75+
/// Define if we may read up to 8 bytes beyond the input buffer.
76+
#define INBUF_PADDED 1
77+
78+
typedef struct LZOContext {
79+
const uint8_t *in, *in_end;
80+
uint8_t *out_start, *out, *out_end;
81+
int error;
82+
} LZOContext;
83+
84+
/**
85+
* @brief Reads one byte from the input buffer, avoiding an overrun.
86+
* @return byte read
87+
*/
88+
static inline int get_byte(LZOContext *c)
89+
{
90+
if (c->in < c->in_end)
91+
return *c->in++;
92+
c->error |= AV_LZO_INPUT_DEPLETED;
93+
return 1;
94+
}
95+
96+
#ifdef INBUF_PADDED
97+
#define GETB(c) (*(c).in++)
98+
#else
99+
#define GETB(c) get_byte(&(c))
100+
#endif
101+
102+
/**
103+
* @brief Decodes a length value in the coding used by lzo.
104+
* @param x previous byte value
105+
* @param mask bits used from x
106+
* @return decoded length value
107+
*/
108+
static inline int get_len(LZOContext *c, int x, int mask)
109+
{
110+
int cnt = x & mask;
111+
if (!cnt) {
112+
while (!(x = get_byte(c))) {
113+
if (cnt >= INT_MAX - 1000) {
114+
c->error |= AV_LZO_ERROR;
115+
break;
116+
}
117+
cnt += 255;
118+
}
119+
cnt += mask + x;
120+
}
121+
return cnt;
122+
}
123+
124+
/**
125+
* @brief Copies bytes from input to output buffer with checking.
126+
* @param cnt number of bytes to copy, must be >= 0
127+
*/
128+
static inline void copy(LZOContext *c, int cnt)
129+
{
130+
register const uint8_t *src = c->in;
131+
register uint8_t *dst = c->out;
132+
av_assert0(cnt >= 0);
133+
if (cnt > c->in_end - src) {
134+
cnt = FFMAX(c->in_end - src, 0);
135+
c->error |= AV_LZO_INPUT_DEPLETED;
136+
}
137+
if (cnt > c->out_end - dst) {
138+
cnt = FFMAX(c->out_end - dst, 0);
139+
c->error |= AV_LZO_OUTPUT_FULL;
140+
}
141+
#if defined(INBUF_PADDED) && defined(OUTBUF_PADDED)
142+
AV_COPY32U(dst, src);
143+
src += 4;
144+
dst += 4;
145+
cnt -= 4;
146+
if (cnt > 0)
147+
#endif
148+
memcpy(dst, src, cnt);
149+
c->in = src + cnt;
150+
c->out = dst + cnt;
151+
}
152+
153+
/**
154+
* @brief Copies previously decoded bytes to current position.
155+
* @param back how many bytes back we start, must be > 0
156+
* @param cnt number of bytes to copy, must be > 0
157+
*
158+
* cnt > back is valid, this will copy the bytes we just copied,
159+
* thus creating a repeating pattern with a period length of back.
160+
*/
161+
static inline void copy_backptr(LZOContext *c, int back, int cnt)
162+
{
163+
register uint8_t *dst = c->out;
164+
av_assert0(cnt > 0);
165+
if (dst - c->out_start < back) {
166+
c->error |= AV_LZO_INVALID_BACKPTR;
167+
return;
168+
}
169+
if (cnt > c->out_end - dst) {
170+
cnt = FFMAX(c->out_end - dst, 0);
171+
c->error |= AV_LZO_OUTPUT_FULL;
172+
}
173+
av_memcpy_backptr(dst, back, cnt);
174+
c->out = dst + cnt;
175+
}
176+
177+
int av_lzo1x_decode(void *out, size_t *outlen, const void *in, size_t *inlen)
178+
{
179+
int state = 0;
180+
int x;
181+
LZOContext c;
182+
if (*outlen <= 0 || *inlen <= 0) {
183+
int res = AV_LZO_SUCCESS;
184+
if (*outlen <= 0)
185+
res |= AV_LZO_OUTPUT_FULL;
186+
if (*inlen <= 0)
187+
res |= AV_LZO_INPUT_DEPLETED;
188+
return res;
189+
}
190+
c.in = in;
191+
c.in_end = (const uint8_t *)in + *inlen;
192+
c.out = c.out_start = out;
193+
c.out_end = (uint8_t *)out + *outlen;
194+
c.error = AV_LZO_SUCCESS;
195+
x = GETB(c);
196+
if (x > 17) {
197+
copy(&c, x - 17);
198+
x = GETB(c);
199+
if (x < 16)
200+
c.error |= AV_LZO_ERROR;
201+
}
202+
if (c.in > c.in_end)
203+
c.error |= AV_LZO_INPUT_DEPLETED;
204+
while (c.error == AV_LZO_SUCCESS) {
205+
int cnt, back;
206+
if (x > 15) {
207+
if (x > 63) {
208+
cnt = (x >> 5) - 1;
209+
back = (GETB(c) << 3) + ((x >> 2) & 7) + 1;
210+
} else if (x > 31) {
211+
cnt = get_len(&c, x, 31);
212+
x = GETB(c);
213+
back = (GETB(c) << 6) + (x >> 2) + 1;
214+
} else {
215+
cnt = get_len(&c, x, 7);
216+
back = (1 << 14) + ((x & 8) << 11);
217+
x = GETB(c);
218+
back += (GETB(c) << 6) + (x >> 2);
219+
if (back == (1 << 14)) {
220+
if (cnt != 1)
221+
c.error |= AV_LZO_ERROR;
222+
break;
223+
}
224+
}
225+
} else if (!state) {
226+
cnt = get_len(&c, x, 15);
227+
copy(&c, cnt + 3);
228+
x = GETB(c);
229+
if (x > 15)
230+
continue;
231+
cnt = 1;
232+
back = (1 << 11) + (GETB(c) << 2) + (x >> 2) + 1;
233+
} else {
234+
cnt = 0;
235+
back = (GETB(c) << 2) + (x >> 2) + 1;
236+
}
237+
copy_backptr(&c, back, cnt + 2);
238+
state =
239+
cnt = x & 3;
240+
copy(&c, cnt);
241+
x = GETB(c);
242+
}
243+
*inlen = c.in_end - c.in;
244+
if (c.in > c.in_end)
245+
*inlen = 0;
246+
*outlen = *outlen - (c.out_end - c.out);
247+
return c.error;
248+
}

libmatroska2/lavu_lzo/lzo.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* LZO 1x decompression
3+
* copyright (c) 2006 Reimar Doeffinger
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+
#ifndef AVUTIL_LZO_H
23+
#define AVUTIL_LZO_H
24+
25+
/**
26+
* @defgroup lavu_lzo LZO
27+
* @ingroup lavu_crypto
28+
*
29+
* @{
30+
*/
31+
32+
#include <stdint.h>
33+
34+
/** @name Error flags returned by av_lzo1x_decode
35+
* @{ */
36+
#define AV_LZO_SUCCESS 0
37+
/// end of the input buffer reached before decoding finished
38+
#define AV_LZO_INPUT_DEPLETED 1
39+
/// decoded data did not fit into output buffer
40+
#define AV_LZO_OUTPUT_FULL 2
41+
/// a reference to previously decoded data was wrong
42+
#define AV_LZO_INVALID_BACKPTR 4
43+
/// a non-specific error in the compressed bitstream
44+
#define AV_LZO_ERROR 8
45+
/** @} */
46+
47+
#define AV_LZO_INPUT_PADDING 8
48+
#define AV_LZO_OUTPUT_PADDING 12
49+
50+
/**
51+
* @brief Decodes LZO 1x compressed data.
52+
* @param out output buffer
53+
* @param outlen size of output buffer, number of bytes left are returned here
54+
* @param in input buffer
55+
* @param inlen size of input buffer, number of bytes left are returned here
56+
* @return 0 on success, otherwise a combination of the error flags above
57+
*
58+
* Make sure all buffers are appropriately padded, in must provide
59+
* AV_LZO_INPUT_PADDING, out must provide AV_LZO_OUTPUT_PADDING additional bytes.
60+
*/
61+
int av_lzo1x_decode(void *out, size_t *outlen, const void *in, size_t *inlen);
62+
63+
/**
64+
* @}
65+
*/
66+
67+
#endif /* AVUTIL_LZO_H */

0 commit comments

Comments
 (0)