1 |
root |
1.1 |
/* |
2 |
|
|
* LZV decompression written in assembly. |
3 |
|
|
* |
4 |
|
|
* Written by Antoine de Maricourt (dumesnil@etca.fr) |
5 |
|
|
* 15 Mar 1995 |
6 |
|
|
* |
7 |
|
|
* NOTE: The use of this algorithm may be restricted by some |
8 |
|
|
* patent. Please check if this is the case in your |
9 |
|
|
* country before using it. |
10 |
|
|
* |
11 |
|
|
* Interface : |
12 |
|
|
* ----------- |
13 |
|
|
* |
14 |
|
|
* int rLZV1 (char *ib, char *ob, int il, int ol); |
15 |
|
|
* |
16 |
|
|
* ib = input buffer (compressed data) |
17 |
|
|
* ob = output buffer (uncompressed data) |
18 |
|
|
* il = number of bytes in the input buffer |
19 |
|
|
* ol = number of bytes to be uncompressed |
20 |
|
|
* |
21 |
|
|
* The routine may write more (i.e., 264) bytes than requested |
22 |
|
|
* (and could be modified in order to write exactly the requested |
23 |
|
|
* number if this is really important). However, it will not write |
24 |
|
|
* more than the original number of bytes in the uncompressed |
25 |
|
|
* data. The returned value is the number of bytes written to |
26 |
|
|
* output buffer. |
27 |
|
|
* |
28 |
|
|
* The algorithm and the coding method have been taken from |
29 |
|
|
* file lzv.c originaly written by Hermann Vogt, and whose |
30 |
|
|
* original copyright notice follows: |
31 |
|
|
* |
32 |
|
|
* ------- |
33 |
|
|
* Copyright (c) 1994 Hermann Vogt. Redistribution of this file is |
34 |
|
|
* permitted under the GNU Public Licence. |
35 |
|
|
* |
36 |
|
|
* The method presented here is faster and compresses better |
37 |
|
|
* than lzrw1 and lzrw1-a. I named it lzv for "Lev-Zimpel-Vogt". |
38 |
|
|
* It uses ideas introduced by Ross Williams in his algorithm |
39 |
|
|
* lzrw1 [R. N. Williams (1991): "An Extremly Fast ZIV-Lempel Data |
40 |
|
|
* Compression Algorithm", Proceedings IEEE Data Compression |
41 |
|
|
* Conference, Snowbird, Utah, 362-371] and by Fiala and Green |
42 |
|
|
* in their algorithm a1 [E. R. Fiala, D. H. Greene (1989): |
43 |
|
|
* "Data Compression with Finite Windows", Communications of the |
44 |
|
|
* ACM, 4, 490-505]. Because lzv differs strongly from both, |
45 |
|
|
* I hope there will be no patent problems. The hashing-method |
46 |
|
|
* has been stolen from Jean-loup Gailly's (patent free) gzip. |
47 |
|
|
* ------- |
48 |
|
|
* Copyright (c) 1995 Antoine de Maricourt. Redistribution |
49 |
|
|
* of this file is permitted under the GNU Public License. |
50 |
|
|
*/ |
51 |
|
|
|
52 |
|
|
#include <linux/linkage.h> |
53 |
|
|
|
54 |
|
|
#define A0 28 |
55 |
|
|
#define A1 32 |
56 |
|
|
#define A2 36 |
57 |
|
|
#define A3 40 |
58 |
|
|
|
59 |
|
|
.text |
60 |
|
|
ENTRY(ext2_LZV1_decompress) |
61 |
|
|
pushl %ebp |
62 |
|
|
pushl %edi |
63 |
|
|
pushl %esi |
64 |
|
|
pushl %ebx # be safe |
65 |
|
|
pushl %ecx |
66 |
|
|
pushl %edx |
67 |
|
|
|
68 |
|
|
movl A0(%esp), %esi # esi = input buffer |
69 |
|
|
movl A1(%esp), %edi # edi = output buffer |
70 |
|
|
movl %esi, %ebx |
71 |
|
|
addl A2(%esp), %ebx # ebx = input limit |
72 |
|
|
movl %edi, %edx |
73 |
|
|
addl A3(%esp), %edx # edx = output limit |
74 |
|
|
xorl %ecx, %ecx |
75 |
|
|
xorl %eax, %eax |
76 |
|
|
cld |
77 |
|
|
|
78 |
|
|
ALIGN |
79 |
|
|
|
80 |
|
|
L10: cmpl %esi, %ebx # check for input overflow |
81 |
|
|
jna L13 |
82 |
|
|
|
83 |
|
|
/* |
84 |
|
|
* Get the opcode |
85 |
|
|
*/ |
86 |
|
|
|
87 |
|
|
movb (%esi), %al # load opcode |
88 |
|
|
testb $7, %al # test 3 lower bits |
89 |
|
|
jne L11 |
90 |
|
|
|
91 |
|
|
/* |
92 |
|
|
* This is a literal |
93 |
|
|
*/ |
94 |
|
|
|
95 |
|
|
shrb $3, %al # store its len into ecx |
96 |
|
|
incb %al |
97 |
|
|
movb %al, %cl |
98 |
|
|
incl %esi |
99 |
|
|
rep; movsb |
100 |
|
|
cmpl %edx, %edi # check for output overflow |
101 |
|
|
jb L10 # and continue |
102 |
|
|
jmp L13 |
103 |
|
|
|
104 |
|
|
/* |
105 |
|
|
* This is a match |
106 |
|
|
*/ |
107 |
|
|
|
108 |
|
|
ALIGN |
109 |
|
|
|
110 |
|
|
L11: movb %al, %cl |
111 |
|
|
andb $7, %cl # store its len into ecx |
112 |
|
|
cmpb $7, %cl |
113 |
|
|
je L12 |
114 |
|
|
|
115 |
|
|
/* |
116 |
|
|
* This is a small match |
117 |
|
|
*/ |
118 |
|
|
|
119 |
|
|
addl $2, %ecx |
120 |
|
|
shll $5, %eax # store the offset into eax |
121 |
|
|
movb 1(%esi), %al |
122 |
|
|
notl %eax |
123 |
|
|
lea 2(%esi), %ebp # save next value of esi |
124 |
|
|
lea (%edi,%eax), %esi # load pointer to match |
125 |
|
|
cmpl A1(%esp), %esi # safety check |
126 |
|
|
jb L13 |
127 |
|
|
rep; movsb # copy the match |
128 |
|
|
xorl %eax, %eax |
129 |
|
|
movl %ebp, %esi # restore esi |
130 |
|
|
cmpl %edx, %edi # check for output overflow |
131 |
|
|
jb L10 # and continue |
132 |
|
|
jmp L13 |
133 |
|
|
|
134 |
|
|
/* |
135 |
|
|
* This is a big match |
136 |
|
|
*/ |
137 |
|
|
|
138 |
|
|
ALIGN |
139 |
|
|
|
140 |
|
|
L12: movb 1(%esi), %cl |
141 |
|
|
addl $9, %ecx |
142 |
|
|
shll $5, %eax # store the offset into eax |
143 |
|
|
movb 2(%esi), %al |
144 |
|
|
notl %eax |
145 |
|
|
lea 3(%esi), %ebp # save next value of esi |
146 |
|
|
lea (%edi,%eax), %esi # load pointer to match |
147 |
|
|
cmpl A1(%esp), %esi # safety check |
148 |
|
|
jb L13 |
149 |
|
|
rep; movsb # copy the match |
150 |
|
|
xorl %eax, %eax |
151 |
|
|
movl %ebp, %esi # restore esi |
152 |
|
|
cmpl %edx, %edi # check for output overflow |
153 |
|
|
jb L10 # and continue |
154 |
|
|
|
155 |
|
|
/* |
156 |
|
|
* The end. |
157 |
|
|
*/ |
158 |
|
|
|
159 |
|
|
L13: movl %edi, %eax |
160 |
|
|
subl A1(%esp),%eax |
161 |
|
|
|
162 |
|
|
popl %edx |
163 |
|
|
popl %ecx |
164 |
|
|
popl %ebx |
165 |
|
|
popl %esi |
166 |
|
|
popl %edi |
167 |
|
|
popl %ebp |
168 |
|
|
ret |