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
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 *
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
f48a01a0d3dc Avoid void *-arithmetic
reimar
parents: 3947
diff changeset
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
f48a01a0d3dc Avoid void *-arithmetic
reimar
parents: 3947
diff changeset
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 }