Mercurial > libavcodec.hg
annotate lzo.c @ 3990:746a60ba3177 libavcodec
enable CMOV_IS_FAST as its faster or equal speed on every cpu (duron, athlon, PM, P3) from which ive seen benchmarks, it might be slower on P4 but noone has posted benchmarks ...
author | michael |
---|---|
date | Wed, 11 Oct 2006 12:23:40 +0000 |
parents | f48a01a0d3dc |
children | 426ccc1cd1ae |
rev | line source |
---|---|
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
1 /* |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
2 * LZO 1x decompression |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
3 * Copyright (c) 2006 Reimar Doeffinger |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
4 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3060
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3060
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3060
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
8 * modify it under the terms of the GNU Lesser General Public |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
9 * License as published by the Free Software Foundation; either |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3060
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3060
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
15 * Lesser General Public License for more details. |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
16 * |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
17 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3060
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
3034
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
20 */ |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
21 #include "common.h" |
3060
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
22 //! avoid e.g. MPlayers fast_memcpy, it slows things down here |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
23 #undef memcpy |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
24 #include <string.h> |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
25 #include "lzo.h" |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
26 |
3060
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
27 //! define if we may write up to 12 bytes beyond the output buffer |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
28 #define OUTBUF_PADDED 1 |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
29 //! define if we may read up to 4 bytes beyond the input buffer |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
30 #define INBUF_PADDED 1 |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
31 typedef struct LZOContext { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
32 uint8_t *in, *in_end; |
3060
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
33 uint8_t *out_start, *out, *out_end; |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
34 int error; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
35 } LZOContext; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
36 |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
37 /** |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
38 * \brief read one byte from input buffer, avoiding overrun |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
39 * \return byte read |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
40 */ |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
41 static inline int get_byte(LZOContext *c) { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
42 if (c->in < c->in_end) |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
43 return *c->in++; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
44 c->error |= LZO_INPUT_DEPLETED; |
3049
9f85c9cf6034
10l, get_byte returning 0 on error can cause a hang. So let's try with 1 instead...
reimar
parents:
3042
diff
changeset
|
45 return 1; |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
46 } |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
47 |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
48 /** |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
49 * \brief decode a length value in the coding used by lzo |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
50 * \param x previous byte value |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
51 * \param mask bits used from x |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
52 * \return decoded length value |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
53 */ |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
54 static inline int get_len(LZOContext *c, int x, int mask) { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
55 int cnt = x & mask; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
56 if (!cnt) { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
57 while (!(x = get_byte(c))) cnt += 255; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
58 cnt += mask + x; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
59 } |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
60 return cnt; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
61 } |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
62 |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
63 /** |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
64 * \brief copy bytes from input to output buffer with checking |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
65 * \param cnt number of bytes to copy, must be > 0 |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
66 */ |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
67 static inline void copy(LZOContext *c, int cnt) { |
3060
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
68 register uint8_t *src = c->in; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
69 register uint8_t *dst = c->out; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
70 if (src + cnt > c->in_end) { |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
71 cnt = c->in_end - src; |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
72 c->error |= LZO_INPUT_DEPLETED; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
73 } |
3060
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
74 if (dst + cnt > c->out_end) { |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
75 cnt = c->out_end - dst; |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
76 c->error |= LZO_OUTPUT_FULL; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
77 } |
3060
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
78 #if defined(INBUF_PADDED) && defined(OUTBUF_PADDED) |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
79 dst[0] = src[0]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
80 dst[1] = src[1]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
81 dst[2] = src[2]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
82 dst[3] = src[3]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
83 src += 4; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
84 dst += 4; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
85 cnt -= 4; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
86 if (cnt > 0) |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
87 #endif |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
88 memcpy(dst, src, cnt); |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
89 c->in = src + cnt; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
90 c->out = dst + cnt; |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
91 } |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
92 |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
93 /** |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
94 * \brief copy previously decoded bytes to current position |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
95 * \param back how many bytes back we start |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
96 * \param cnt number of bytes to copy, must be > 0 |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
97 * |
3060
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
98 * cnt > back is valid, this will copy the bytes we just copied, |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
99 * thus creating a repeating pattern with a period length of back. |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
100 */ |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
101 static inline void copy_backptr(LZOContext *c, int back, int cnt) { |
3060
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
102 register uint8_t *src = &c->out[-back]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
103 register uint8_t *dst = c->out; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
104 if (src < c->out_start) { |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
105 c->error |= LZO_INVALID_BACKPTR; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
106 return; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
107 } |
3060
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
108 if (dst + cnt > c->out_end) { |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
109 cnt = c->out_end - dst; |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
110 c->error |= LZO_OUTPUT_FULL; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
111 } |
3060
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
112 if (back == 1) { |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
113 memset(dst, *src, cnt); |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
114 dst += cnt; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
115 } else { |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
116 #ifdef OUTBUF_PADDED |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
117 dst[0] = src[0]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
118 dst[1] = src[1]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
119 dst[2] = src[2]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
120 dst[3] = src[3]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
121 src += 4; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
122 dst += 4; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
123 cnt -= 4; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
124 if (cnt > 0) { |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
125 dst[0] = src[0]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
126 dst[1] = src[1]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
127 dst[2] = src[2]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
128 dst[3] = src[3]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
129 dst[4] = src[4]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
130 dst[5] = src[5]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
131 dst[6] = src[6]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
132 dst[7] = src[7]; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
133 src += 8; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
134 dst += 8; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
135 cnt -= 8; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
136 } |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
137 #endif |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
138 if (cnt > 0) { |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
139 int blocklen = back; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
140 while (cnt > blocklen) { |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
141 memcpy(dst, src, blocklen); |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
142 dst += blocklen; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
143 cnt -= blocklen; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
144 blocklen <<= 1; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
145 } |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
146 memcpy(dst, src, cnt); |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
147 } |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
148 dst += cnt; |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
149 } |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
150 c->out = dst; |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
151 } |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
152 |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
153 /** |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
154 * \brief decode LZO 1x compressed data |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
155 * \param out output buffer |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
156 * \param outlen size of output buffer, number of bytes left are returned here |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
157 * \param in input buffer |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
158 * \param inlen size of input buffer, number of bytes left are returned here |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
159 * \return 0 on success, otherwise error flags, see lzo.h |
3060
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
160 * |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
161 * make sure all buffers are appropriately padded, in must provide |
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
162 * LZO_INPUT_PADDING, out must provide LZO_OUTPUT_PADDING additional bytes |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
163 */ |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
164 int lzo1x_decode(void *out, int *outlen, void *in, int *inlen) { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
165 enum {COPY, BACKPTR} state = COPY; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
166 int x; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
167 LZOContext c; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
168 c.in = in; |
3958 | 169 c.in_end = (uint8_t *)in + *inlen; |
3060
a2f611d6c34d
faster copy functions for lzo decoder that also need padding
reimar
parents:
3049
diff
changeset
|
170 c.out = c.out_start = out; |
3958 | 171 c.out_end = (uint8_t *)out + * outlen; |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
172 c.error = 0; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
173 x = get_byte(&c); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
174 if (x > 17) { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
175 copy(&c, x - 17); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
176 x = get_byte(&c); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
177 if (x < 16) c.error |= LZO_ERROR; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
178 } |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
179 while (!c.error) { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
180 int cnt, back; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
181 if (x >> 4) { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
182 if (x >> 6) { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
183 cnt = (x >> 5) - 1; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
184 back = (get_byte(&c) << 3) + ((x >> 2) & 7) + 1; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
185 } else if (x >> 5) { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
186 cnt = get_len(&c, x, 31); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
187 x = get_byte(&c); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
188 back = (get_byte(&c) << 6) + (x >> 2) + 1; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
189 } else { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
190 cnt = get_len(&c, x, 7); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
191 back = (1 << 14) + ((x & 8) << 11); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
192 x = get_byte(&c); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
193 back += (get_byte(&c) << 6) + (x >> 2); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
194 if (back == (1 << 14)) { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
195 if (cnt != 1) |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
196 c.error |= LZO_ERROR; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
197 break; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
198 } |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
199 } |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
200 } else |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
201 switch (state) { |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
202 case COPY: |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
203 cnt = get_len(&c, x, 15); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
204 copy(&c, cnt + 3); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
205 x = get_byte(&c); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
206 if (x >> 4) |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
207 continue; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
208 cnt = 1; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
209 back = (1 << 11) + (get_byte(&c) << 2) + (x >> 2) + 1; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
210 break; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
211 case BACKPTR: |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
212 cnt = 0; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
213 back = (get_byte(&c) << 2) + (x >> 2) + 1; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
214 break; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
215 } |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
216 copy_backptr(&c, back, cnt + 2); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
217 cnt = x & 3; |
3041
241b3a9bbd0c
Wrong state handling causing decompression errors in some cases
reimar
parents:
3036
diff
changeset
|
218 state = cnt ? BACKPTR : COPY; |
3034
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
219 if (cnt) |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
220 copy(&c, cnt); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
221 x = get_byte(&c); |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
222 } |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
223 *inlen = c.in_end - c.in; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
224 *outlen = c.out_end - c.out; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
225 return c.error; |
d37065d8aeff
Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff
changeset
|
226 } |