Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1805 yogev_ezra 1
; Exports only one function:
2
; void __stdcall lzma_decompress(
3
;	const void* source,
4
;	void* destination,
5
;	unsigned dest_length);
6
 
7
	format COFF
8
 
9
section '.text' code
10
 
11
pb	equ	2	; pos state bits
12
lp	equ	0	; literal pos state bits
13
lc	equ	3	; literal context bits
14
posStateMask	equ	((1 shl pb)-1)
15
literalPosMask	equ	((1 shl lp)-1)
16
 
17
kNumPosBitsMax	=	4
18
kNumPosStatesMax =	(1 shl kNumPosBitsMax)
19
 
20
kLenNumLowBits	=	3
21
kLenNumLowSymbols =	(1 shl kLenNumLowBits)
22
kLenNumMidBits	=	3
23
kLenNumMidSymbols =	(1 shl kLenNumMidBits)
24
kLenNumHighBits	=	8
25
kLenNumHighSymbols =	(1 shl kLenNumHighBits)
26
 
27
LenChoice	=	0
28
LenChoice2	=	1
29
LenLow		=	2
30
LenMid		=	(LenLow + (kNumPosStatesMax shl kLenNumLowBits))
31
LenHigh		=	(LenMid + (kNumPosStatesMax shl kLenNumMidBits))
32
kNumLenProbs	=	(LenHigh + kLenNumHighSymbols)
33
 
34
kNumStates	=	12
35
kNumLitStates	=	7
36
kStartPosModelIndex =	4
37
kEndPosModelIndex =	14
38
kNumFullDistances =	(1 shl (kEndPosModelIndex/2))
39
kNumPosSlotBits =	6
40
kNumLenToPosStates =	4
41
kNumAlignBits	=	4
42
kAlignTableSize	=	(1 shl kNumAlignBits)
43
kMatchMinLen	=	2
44
 
45
IsMatch		=	0
46
IsRep		=	0xC0	; (IsMatch + (kNumStates shl kNumPosBitsMax))
47
IsRepG0		=	0xCC	; (IsRep + kNumStates)
48
IsRepG1		=	0xD8	; (IsRepG0 + kNumStates)
49
IsRepG2		=	0xE4	; (IsRepG1 + kNumStates)
50
IsRep0Long	=	0xF0	; (IsRepG2 + kNumStates)
51
PosSlot		=	0x1B0	; (IsRep0Long + (kNumStates shl kNumPosBitsMax))
52
SpecPos		=	0x2B0	; (PosSlot + (kNumLenToPosStates shl kNumPosSlotBits))
53
Align_		=	0x322	; (SpecPos + kNumFullDistances - kEndPosModelIndex)
54
Lencoder	=	0x332	; (Align_ + kAlignTableSize)
55
RepLencoder	=	0x534	; (Lencoder + kNumLenProbs)
56
Literal		=	0x736	; (RepLencoder + kNumLenProbs)
57
 
58
LZMA_BASE_SIZE	=	1846	; must be ==Literal
59
LZMA_LIT_SIZE	=	768
60
 
61
kNumTopBits	=	24
62
kTopValue	=	(1 shl kNumTopBits)
63
 
64
kNumBitModelTotalBits =	11
65
kBitModelTotal	=	(1 shl kNumBitModelTotalBits)
66
kNumMoveBits	=	5
67
 
68
RangeDecoderBitDecode:
69
; in: eax->prob
70
; out: CF=bit
71
	push	edx
72
	mov	edx, [range]
73
	shr	edx, kNumBitModelTotalBits
74
	imul	edx, [eax]
75
	cmp	[code_], edx
76
	jae	.ae
77
	mov	[range], edx
78
	mov	edx, kBitModelTotal
79
	sub	edx, [eax]
80
	shr	edx, kNumMoveBits
81
	add	[eax], edx
82
.n:
83
	pushfd
84
	call	update_decoder
85
	popfd
86
	pop	edx
87
	ret
88
.ae:
89
	sub	[range], edx
90
	sub	[code_], edx
91
	mov	edx, [eax]
92
	shr	edx, kNumMoveBits
93
	sub	[eax], edx
94
	stc
95
	jmp	.n
96
 
97
update_decoder:
98
	cmp	byte [range+3], 0	;cmp	dword [range], kTopValue
99
	jnz	@f			;jae	@f
100
	shl	dword [range], 8
101
	shl	dword [code_], 8
102
	push	eax
103
	mov	eax, [inptr]
104
	mov	al, [eax]
105
	inc	dword [inptr]
106
	mov	byte [code_], al
107
	pop	eax
108
@@:	ret
109
 
110
LzmaLenDecode:
111
; in: eax->prob, edx=posState
112
; out: ecx=len
113
 
114
; LenChoice==0
115
;	add	eax, LenChoice*4
116
	call	RangeDecoderBitDecode
117
	jnc	.0
118
	add	eax, (LenChoice2-LenChoice)*4
119
	call	RangeDecoderBitDecode
120
	jc	@f
121
	mov	cl, kLenNumMidBits
122
	shl	edx, cl
123
	lea	eax, [eax + (LenMid-LenChoice2)*4 + edx*4]
124
	call	RangeDecoderBitTreeDecode
125
	add	ecx, kLenNumLowSymbols
126
	ret
127
@@:
128
	add	eax, (LenHigh-LenChoice2)*4
129
	mov	cl, kLenNumHighBits
130
	call	RangeDecoderBitTreeDecode
131
	add	ecx, kLenNumLowSymbols + kLenNumMidSymbols
132
	ret
133
.0:
134
	mov	cl, kLenNumLowBits
135
	shl	edx, cl
136
	lea	eax, [eax + LenLow*4 + edx*4]
137
RangeDecoderBitTreeDecode:
138
; in: eax->probs,ecx=numLevels
139
; out: ecx=length; destroys edx
140
	push	edi
141
	xor	edx, edx
142
	inc	edx
143
	mov	edi, edx
144
	xchg	eax, edi
145
@@:
146
	push	eax
147
	lea	eax, [edi+edx*4]
148
	call	RangeDecoderBitDecode
149
	pop	eax
150
	adc	dl, dl
151
	add	al, al
152
	loop	@b
153
	sub	dl, al
154
	pop	edi
155
	mov	ecx, edx
156
	ret
157
 
158
; void __stdcall lzma_decompress(
159
;	const void* source,
160
;	void* destination,
161
;	unsigned dest_length);
162
lzma_decompress equ _lzma_decompress@12
163
public lzma_decompress
164
lzma_decompress:
165
	push	esi edi ebx ebp
166
	mov	esi, [esp+4*4+4]	; source
167
	xor	ebp, ebp
168
	mov	edi, code_
169
	inc	esi
170
	lodsd
171
	bswap	eax
172
	stosd
173
	xor	eax, eax
174
	dec	eax
175
	stosd
176
	stosd
177
	stosd
178
	stosd
179
	xchg	eax, esi
180
	stosd
181
	mov	ecx, Literal + (LZMA_LIT_SIZE shl (lc+lp))
182
	mov	eax, kBitModelTotal/2
183
	mov	edi, p
184
	rep	stosd
185
	mov	edi, [esp+4*4+8]	; destination
186
	mov	ebx, edi
187
	add	ebx, [esp+4*4+12]	; dest_length
188
.main_loop:
189
	cmp	edi, ebx
190
	jae	.main_loop_done
191
	mov	edx, edi
192
	and	edx, posStateMask
193
	push	eax	; al = previous byte
194
	mov	eax, ebp
195
	shl	eax, kNumPosBitsMax+2
196
	lea	eax, [p + IsMatch*4 + eax + edx*4]
197
	call	RangeDecoderBitDecode
198
	pop	eax
199
	jc	.1
200
	movzx	eax, al
201
if literalPosMask
202
	mov	ah, dl
203
	and	ah, literalPosMask
204
end if
205
	shr	eax, 8-lc
206
	imul	eax, LZMA_LIT_SIZE*4
207
	add	eax, p+Literal*4
208
	mov	cl, 1
209
	cmp	ebp, kNumLitStates
210
	jb	.literal
211
	mov	dl, [edi + esi]
212
.lx0:
213
	add	dl, dl
214
	setc	ch
215
	push	eax
216
	lea	eax, [eax+ecx*4+0x100*4]
217
	call	RangeDecoderBitDecode
218
	pop	eax
219
	adc	cl, cl
220
	jc	.lx1
221
	xor	ch, cl
222
	test	ch, 1
223
	mov	ch, 0
224
	jz	.lx0
225
.literal:
226
@@:
227
	push	eax
228
	lea	eax, [eax+ecx*4]
229
	call	RangeDecoderBitDecode
230
	pop	eax
231
	adc	cl, cl
232
	jnc	@b
233
.lx1:
234
	mov	eax, ebp
235
	cmp	al, 4
236
	jb	@f
237
	cmp	al, 10
238
	mov	al, 3
239
	jb	@f
240
	mov	al, 6
241
@@:	sub	ebp, eax
242
	xchg	eax, ecx
243
.stosb_main_loop:
244
	stosb
245
	jmp	.main_loop
246
.1:
247
	lea	eax, [p + IsRep*4 + ebp*4]
248
	call	RangeDecoderBitDecode
249
	jnc	.10
250
	add	eax, (IsRepG0 - IsRep)*4	;lea	eax, [p + IsRepG0*4 + ebp*4]
251
	call	RangeDecoderBitDecode
252
	jc	.111
253
	mov	eax, ebp
254
	shl	eax, kNumPosBitsMax+2
255
	lea	eax, [p + IsRep0Long*4 + eax + edx*4]
256
	call	RangeDecoderBitDecode
257
	jc	.1101
258
	cmp	ebp, 7
259
	sbb	ebp, ebp
260
	lea	ebp, [ebp+ebp+11]
261
	mov	al, [edi + esi]
262
	jmp	.stosb_main_loop
263
.111:
264
	add	eax, (IsRepG1 - IsRepG0) * 4	;lea	eax, [p + IsRepG1*4 + ebp*4]
265
	call	RangeDecoderBitDecode
266
	xchg	esi, [rep1]
267
	jnc	@f
268
	add	eax, (IsRepG2 - IsRepG1) * 4	;lea	eax, [p + IsRepG2*4 + ebp*4]
269
	call	RangeDecoderBitDecode
270
	xchg	esi, [rep2]
271
	jnc	@f
272
	xchg	esi, [rep3]
273
@@:
274
.1101:
275
	mov	eax, p + RepLencoder*4
276
	call	LzmaLenDecode
277
	push	8
278
	jmp	.rmu
279
.10:
280
	xchg	esi, [rep1]
281
	xchg	esi, [rep2]
282
	mov	[rep3], esi
283
	mov	eax, p + Lencoder*4
284
	call	LzmaLenDecode
285
	push	kNumLenToPosStates-1
286
	pop	eax
287
	cmp	eax, ecx
288
	jb	@f
289
	mov	eax, ecx
290
@@:
291
	push	ecx
292
	push	kNumPosSlotBits
293
	pop	ecx
294
	shl	eax, cl
295
	shl	eax, 2
296
	add	eax, p+PosSlot*4
297
	call	RangeDecoderBitTreeDecode
298
	mov	esi, ecx
299
	cmp	ecx, kStartPosModelIndex
300
	jb	.l6
301
	push	ecx
302
	xor	eax, eax
303
	inc	eax
304
	shr	ecx, 1
305
	adc	al, al
306
	dec	ecx
307
	shl	eax, cl
308
	mov	esi, eax
309
	pop	edx
310
	cmp	edx, kEndPosModelIndex
311
	jae	.l5
312
	sub	eax, edx
313
	shl	eax, 2
314
	add	eax, p + (SpecPos - 1)*4
315
	jmp	.l59
316
.l5:
317
	sub	ecx, kNumAlignBits
318
;	call	RangeDecoderDecodeDirectBits
319
;RangeDecoderDecodeDirectBits:
320
	xor	eax, eax
321
.l:
322
	shr	dword [range], 1
323
	add	eax, eax
324
	mov	edx, [code_]
325
	sub	edx, [range]
326
	jb	@f
327
	mov	[code_], edx
328
	inc	eax
329
@@:
330
	call	update_decoder
331
	loop	.l
332
;	ret
333
	mov	cl, kNumAlignBits
334
	shl	eax, cl
335
	add	esi, eax
336
	mov	eax, p+Align_*4
337
.l59:
338
;	call	RangeDecoderReverseBitTreeDecode_addesi
339
;_RangeDecoderReverseBitTreeDecode_addesi:
340
; in: eax->probs,ecx=numLevels
341
; out: esi+=length; destroys edx
342
	push	edi ecx
343
	xor	edx, edx
344
	inc	edx
345
	xor	edi, edi
346
@@:
347
	push	eax
348
	lea	eax, [eax+edx*4]
349
	call	RangeDecoderBitDecode
350
	lahf
351
	adc	edx, edx
352
	sahf
353
	rcr	edi, 1
354
	pop	eax
355
	loop	@b
356
	pop	ecx
357
	rol	edi, cl
358
	add	esi, edi
359
	pop	edi
360
;	ret
361
.l6:
362
	pop	ecx
363
	not	esi
364
	push	7
365
.rmu:
366
	cmp	ebp, 7
367
	pop	ebp
368
	jb	@f
369
	inc	ebp
370
	inc	ebp
371
	inc	ebp
372
@@:
373
.repmovsb:
374
	inc	ecx
375
	push	esi
376
	add	esi, edi
377
	rep	movsb
378
	lodsb
379
	pop	esi
380
	jmp	.stosb_main_loop
381
.main_loop_done:
382
	pop	ebp ebx edi esi
383
	ret	12
384
 
385
section '.bss' data
386
p	rd	LZMA_BASE_SIZE + (LZMA_LIT_SIZE shl (lc+lp))
387
code_	dd	?
388
range	dd	?
389
rep1	dd	?
390
rep2	dd	?
391
rep3	dd	?
392
inptr	dd	?
393
previousByte db	?