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 |