annotate lzo.c @ 3308:57078a058b96 libavcodec

fix compilation of 3dnowext instinsincs, both on ia32 and AMD64. 3dnow intrinsincs are for now only compiled if 3dnowext support is available. (I should add smth that checks for plain 3dnow later)
author gpoirier
date Tue, 16 May 2006 14:24:45 +0000
parents a2f611d6c34d
children c8c591fe26f8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 *
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
6 * 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
7 * License as published by the Free Software Foundation; either
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
9 *
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
11 * 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
12 * 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
13 * Lesser General Public License for more details.
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
14 *
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
3036
0b546eab515d Update licensing information: The FSF changed postal address.
diego
parents: 3034
diff changeset
17 * 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
18 */
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
19 #include "common.h"
3060
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
20 //! 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
21 #undef memcpy
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
22 #include <string.h>
3034
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
23 #include "lzo.h"
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
24
3060
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
25 //! 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
26 #define OUTBUF_PADDED 1
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
27 //! 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
28 #define INBUF_PADDED 1
3034
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
29 typedef struct LZOContext {
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
30 uint8_t *in, *in_end;
3060
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
31 uint8_t *out_start, *out, *out_end;
3034
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
32 int error;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
33 } LZOContext;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
34
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
35 /**
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
36 * \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
37 * \return byte read
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
38 */
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
39 static inline int get_byte(LZOContext *c) {
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
40 if (c->in < c->in_end)
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
41 return *c->in++;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
42 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
43 return 1;
3034
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
44 }
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
45
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 * \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
48 * \param x previous byte value
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
49 * \param mask bits used from x
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
50 * \return decoded length value
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
51 */
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
52 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
53 int cnt = x & mask;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
54 if (!cnt) {
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
55 while (!(x = get_byte(c))) cnt += 255;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
56 cnt += mask + x;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
57 }
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
58 return cnt;
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
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 * \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
63 * \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
64 */
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
65 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
66 register uint8_t *src = c->in;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
67 register uint8_t *dst = c->out;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
68 if (src + cnt > c->in_end) {
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
69 cnt = c->in_end - src;
3034
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
70 c->error |= LZO_INPUT_DEPLETED;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
71 }
3060
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
72 if (dst + cnt > c->out_end) {
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
73 cnt = c->out_end - dst;
3034
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
74 c->error |= LZO_OUTPUT_FULL;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
75 }
3060
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
76 #if defined(INBUF_PADDED) && defined(OUTBUF_PADDED)
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
77 dst[0] = src[0];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
78 dst[1] = src[1];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
79 dst[2] = src[2];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
80 dst[3] = src[3];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
81 src += 4;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
82 dst += 4;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
83 cnt -= 4;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
84 if (cnt > 0)
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
85 #endif
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
86 memcpy(dst, src, cnt);
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
87 c->in = src + cnt;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
88 c->out = dst + cnt;
3034
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
89 }
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
90
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 * \brief copy previously decoded bytes to current position
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
93 * \param back how many bytes back we start
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
94 * \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
95 *
3060
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
96 * 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
97 * 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
98 */
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
99 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
100 register uint8_t *src = &c->out[-back];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
101 register uint8_t *dst = c->out;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
102 if (src < c->out_start) {
3034
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
103 c->error |= LZO_INVALID_BACKPTR;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
104 return;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
105 }
3060
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
106 if (dst + cnt > c->out_end) {
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
107 cnt = c->out_end - dst;
3034
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
108 c->error |= LZO_OUTPUT_FULL;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
109 }
3060
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
110 if (back == 1) {
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
111 memset(dst, *src, cnt);
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
112 dst += cnt;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
113 } else {
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
114 #ifdef OUTBUF_PADDED
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
115 dst[0] = src[0];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
116 dst[1] = src[1];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
117 dst[2] = src[2];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
118 dst[3] = src[3];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
119 src += 4;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
120 dst += 4;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
121 cnt -= 4;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
122 if (cnt > 0) {
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
123 dst[0] = src[0];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
124 dst[1] = src[1];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
125 dst[2] = src[2];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
126 dst[3] = src[3];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
127 dst[4] = src[4];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
128 dst[5] = src[5];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
129 dst[6] = src[6];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
130 dst[7] = src[7];
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
131 src += 8;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
132 dst += 8;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
133 cnt -= 8;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
134 }
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
135 #endif
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
136 if (cnt > 0) {
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
137 int blocklen = back;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
138 while (cnt > blocklen) {
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
139 memcpy(dst, src, blocklen);
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
140 dst += blocklen;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
141 cnt -= blocklen;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
142 blocklen <<= 1;
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
143 }
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
144 memcpy(dst, src, cnt);
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 dst += 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 c->out = dst;
3034
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
149 }
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
150
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 * \brief decode LZO 1x compressed data
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
153 * \param out output buffer
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
154 * \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
155 * \param in input buffer
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
156 * \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
157 * \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
158 *
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
159 * 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
160 * 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
161 */
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
162 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
163 enum {COPY, BACKPTR} state = COPY;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
164 int x;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
165 LZOContext c;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
166 c.in = in;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
167 c.in_end = in + *inlen;
3060
a2f611d6c34d faster copy functions for lzo decoder that also need padding
reimar
parents: 3049
diff changeset
168 c.out = c.out_start = out;
3034
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
169 c.out_end = out + * outlen;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
170 c.error = 0;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
171 x = get_byte(&c);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
172 if (x > 17) {
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
173 copy(&c, x - 17);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
174 x = get_byte(&c);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
175 if (x < 16) c.error |= LZO_ERROR;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
176 }
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
177 while (!c.error) {
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
178 int cnt, back;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
179 if (x >> 4) {
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
180 if (x >> 6) {
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
181 cnt = (x >> 5) - 1;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
182 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
183 } else if (x >> 5) {
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
184 cnt = get_len(&c, x, 31);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
185 x = get_byte(&c);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
186 back = (get_byte(&c) << 6) + (x >> 2) + 1;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
187 } else {
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
188 cnt = get_len(&c, x, 7);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
189 back = (1 << 14) + ((x & 8) << 11);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
190 x = get_byte(&c);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
191 back += (get_byte(&c) << 6) + (x >> 2);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
192 if (back == (1 << 14)) {
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
193 if (cnt != 1)
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
194 c.error |= LZO_ERROR;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
195 break;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
196 }
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
197 }
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
198 } else
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
199 switch (state) {
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
200 case COPY:
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
201 cnt = get_len(&c, x, 15);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
202 copy(&c, cnt + 3);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
203 x = get_byte(&c);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
204 if (x >> 4)
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
205 continue;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
206 cnt = 1;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
207 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
208 break;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
209 case BACKPTR:
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
210 cnt = 0;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
211 back = (get_byte(&c) << 2) + (x >> 2) + 1;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
212 break;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
213 }
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
214 copy_backptr(&c, back, cnt + 2);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
215 cnt = x & 3;
3041
241b3a9bbd0c Wrong state handling causing decompression errors in some cases
reimar
parents: 3036
diff changeset
216 state = cnt ? BACKPTR : COPY;
3034
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
217 if (cnt)
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
218 copy(&c, cnt);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
219 x = get_byte(&c);
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
220 }
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
221 *inlen = c.in_end - c.in;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
222 *outlen = c.out_end - c.out;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
223 return c.error;
d37065d8aeff Our own LZO (1X) implementation, under LGPL and optimized for readability.
reimar
parents:
diff changeset
224 }