Subversion Repositories Kolibri OS

Rev

Rev 425 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
183 diamond 1
; void __stdcall unpack(void* packed_data, void* unpacked_data);
2
unpack:
3
        pushad
4
        mov     esi, [esp+32+4]
5
        mov     edi, [esp+32+8]
6
        mov     eax, [esi+8]
7
        and     al, 0xC0
8
        cmp     al, 0xC0
9
        jz      .failed
10
        mov     eax, [esi+8]
11
        push    eax
12
        add     esi, 12
13
        and     al, not 0xC0
14
        dec     eax
15
        jz      .lzma
16
.failed:
17
        pop     eax
18
        popad
19
        ret     8
20
.lzma:
21
        call    .lzma_unpack
22
.common:
23
        pop     eax
24
        test    al, 0x80
25
        jnz     .ctr1
26
        test    al, 0x40
27
        jz      .ok
28
        lodsd
29
        mov     ecx, eax
30
        jecxz   .ok
31
        mov     dl, [esi]
32
        mov     esi, [esp+32+8]
33
.c1:
34
        lodsb
35
        sub     al, 0E8h
36
        cmp     al, 1
37
        ja      .c1
38
        cmp     byte [esi], dl
39
        jnz     .c1
40
        lodsd
41
; "bswap eax" is not supported on i386
42
        shr     ax, 8
43
        ror     eax, 16
44
        xchg    al, ah
45
        sub     eax, esi
46
        add     eax, [esp+32+8]
47
        mov     [esi-4], eax
48
        loop    .c1
49
.ok:
50
        popad
51
        ret     8
52
.ctr1:
53
        lodsd
54
        mov     ecx, eax
55
        jecxz   .ok
56
        mov     dl, [esi]
57
        mov     esi, [esp+32+8]
58
.c2:
59
        lodsb
60
@@:
61
        cmp     al, 0xF
62
        jnz     .f
63
        lodsb
64
        cmp     al, 80h
65
        jb      @b
66
        cmp     al, 90h
67
        jb      @f
68
.f:
69
        sub     al, 0E8h
70
        cmp     al, 1
71
        ja      .c2
72
@@:
73
        cmp     byte [esi], dl
74
        jnz     .c2
75
        lodsd
76
        shr     ax, 8
77
        ror     eax, 16
78
        xchg    al, ah
79
        sub     eax, esi
80
        add     eax, [esp+32+8]
81
        mov     [esi-4], eax
82
        loop    .c2
83
        jmp     .ok
84
 
85
.lzma_unpack:
86
 
87
.pb	=	2	; pos state bits
88
.lp	=	0	; literal pos state bits
89
.lc	=	3	; literal context bits
90
.posStateMask	=	((1 shl .pb)-1)
91
.literalPosMask	=	((1 shl .lp)-1)
92
 
93
.kNumPosBitsMax	=	4
94
.kNumPosStatesMax =	(1 shl .kNumPosBitsMax)
95
 
96
.kLenNumLowBits         =       3
97
.kLenNumLowSymbols      =       (1 shl .kLenNumLowBits)
98
.kLenNumMidBits         =       3
99
.kLenNumMidSymbols      =       (1 shl .kLenNumMidBits)
100
.kLenNumHighBits        =       8
101
.kLenNumHighSymbols     =       (1 shl .kLenNumHighBits)
102
 
103
.LenChoice	=	0
104
.LenChoice2	=	1
105
.LenLow		=	2
106
.LenMid		=	(.LenLow + (.kNumPosStatesMax shl .kLenNumLowBits))
107
.LenHigh	=	(.LenMid + (.kNumPosStatesMax shl .kLenNumMidBits))
108
.kNumLenProbs	=	(.LenHigh + .kLenNumHighSymbols)
109
 
110
.kNumStates	=	12
111
.kNumLitStates	=	7
112
.kStartPosModelIndex =	4
113
.kEndPosModelIndex =	14
114
.kNumFullDistances =	(1 shl (.kEndPosModelIndex/2))
115
.kNumPosSlotBits =	6
116
.kNumLenToPosStates =	4
117
.kNumAlignBits	=	4
118
.kAlignTableSize =	(1 shl .kNumAlignBits)
119
.kMatchMinLen	=	2
120
 
121
.IsMatch	=	0
122
.IsRep		=	(.IsMatch + (.kNumStates shl .kNumPosBitsMax))
123
.IsRepG0	=	(.IsRep + .kNumStates)
124
.IsRepG1	=	(.IsRepG0 + .kNumStates)
125
.IsRepG2	=	(.IsRepG1 + .kNumStates)
126
.IsRep0Long	=	(.IsRepG2 + .kNumStates)
127
.PosSlot	=	(.IsRep0Long + (.kNumStates shl .kNumPosBitsMax))
128
.SpecPos	=	(.PosSlot + (.kNumLenToPosStates shl .kNumPosSlotBits))
129
.Align_		=	(.SpecPos + .kNumFullDistances - .kEndPosModelIndex)
130
.Lencoder	=	(.Align_ + .kAlignTableSize)
131
.RepLencoder	=	(.Lencoder + .kNumLenProbs)
132
.Literal	=	(.RepLencoder + .kNumLenProbs)
133
 
134
.LZMA_BASE_SIZE	=	1846	; must be ==Literal
135
.LZMA_LIT_SIZE	=	768
136
 
137
.kNumTopBits	=	24
138
.kTopValue	=	(1 shl .kNumTopBits)
139
 
140
.kNumBitModelTotalBits =	11
141
.kBitModelTotal	=	(1 shl .kNumBitModelTotalBits)
142
.kNumMoveBits	=	5
143
 
144
        push    edi
145
; int state=0;
146
	xor	ebx, ebx
147
	mov	[.previousByte], bl
148
; unsigned rep0=1,rep1=1,rep2=1,rep3=1;
149
	mov	eax, 1
150
	mov	edi, .rep0
151
	stosd
152
	stosd
153
	stosd
154
	stosd
155
; int len=0;
156
; result=0;
157
	mov	ecx, .Literal + (.LZMA_LIT_SIZE shl (.lc+.lp))
158
	mov	eax, .kBitModelTotal/2
159
	mov	edi, .p
160
	rep	stosd
161
; RangeDecoderInit
162
; rd->ExtraBytes = 0
163
; rd->Buffer = stream
164
; rd->BufferLim = stream+bufferSize
165
; rd->Range = 0xFFFFFFFF
166
        pop     edi
167
	mov	ebp, [esi-8]	; dest_length
168
	add	ebp, edi	; ebp = destination limit
169
	lodsd
170
; rd->code_ = eax
171
	mov	[.code_], eax
172
	or	[.range], -1
173
.main_loop:
174
	cmp	edi, ebp
175
	jae	.main_loop_done
176
	mov	edx, edi
177
	and	edx, .posStateMask
178
	mov	eax, ebx
179
	shl	eax, .kNumPosBitsMax+2
180
	lea	eax, [.p + .IsMatch*4 + eax + edx*4]
181
	call	.RangeDecoderBitDecode
182
	jc	.1
183
	movzx	eax, [.previousByte]
184
if .literalPosMask
185
	mov	ah, dl
186
	and	ah, .literalPosMask
187
end if
188
	shr	eax, 8-.lc
189
	imul	eax, .LZMA_LIT_SIZE*4
190
	add	eax, .p+.Literal*4
191
	cmp	ebx, .kNumLitStates
192
	jb	.literal
193
	xor	edx, edx
194
	sub	edx, [.rep0]
195
	mov	dl, [edi + edx]
196
	call	.LzmaLiteralDecodeMatch
197
	jmp	@f
198
.literal:
199
	call	.LzmaLiteralDecode
200
@@:
201
	mov	[.previousByte], al
202
	stosb
203
	mov	al, bl
204
	cmp	bl, 4
205
	jb	@f
206
	mov	al, 3
207
	cmp	bl, 10
208
	jb	@f
209
	mov	al, 6
210
@@:	sub	bl, al
211
	jmp	.main_loop
212
.1:
213
	lea	eax, [.p + .IsRep*4 + ebx*4]
214
	call	.RangeDecoderBitDecode
215
	jnc	.10
216
	lea	eax, [.p + .IsRepG0*4 + ebx*4]
217
	call	.RangeDecoderBitDecode
218
	jc	.111
219
	mov	eax, ebx
220
	shl	eax, .kNumPosBitsMax+2
221
	lea	eax, [.p + .IsRep0Long*4 + eax + edx*4]
222
	call	.RangeDecoderBitDecode
223
	jc	.1101
224
	cmp	bl, 7
225
	setae	bl
226
	lea	ebx, [9 + ebx + ebx]
227
	xor	edx, edx
228
	sub	edx, [.rep0]
229
	mov	al, [edi + edx]
230
	stosb
231
	mov	[.previousByte], al
232
	jmp	.main_loop
233
.111:
234
	lea	eax, [.p + .IsRepG1*4 + ebx*4]
235
	call	.RangeDecoderBitDecode
236
	mov	eax, [.rep1]
237
	jnc	.l3
238
.l1:
239
	lea	eax, [.p + .IsRepG2*4 + ebx*4]
240
	call	.RangeDecoderBitDecode
241
	mov	eax, [.rep2]
242
	jnc	.l2
243
	xchg	[.rep3], eax
244
.l2:
245
	push	[.rep1]
246
	pop	[.rep2]
247
.l3:
248
	xchg	eax, [.rep0]
249
	mov	[.rep1], eax
250
.1101:
251
	mov	eax, .p + .RepLencoder*4
252
	call	.LzmaLenDecode
253
	cmp	bl, 7
254
	setc	bl
255
	adc	bl, bl
256
	xor	bl, 3
257
	add	bl, 8
258
	jmp	.repmovsb
259
.10:
260
	mov	eax, [.rep0]
261
	xchg	eax, [.rep1]
262
	xchg	eax, [.rep2]
263
	xchg	eax, [.rep3]
264
	cmp	bl, 7
265
	setc	bl
266
	adc	bl, bl
267
	xor	bl, 3
268
	add	bl, 7
269
	mov	eax, .p + .Lencoder*4
270
	call	.LzmaLenDecode
271
	mov	eax, .kNumLenToPosStates-1
272
	cmp	eax, ecx
273
	jb	@f
274
	mov	eax, ecx
275
@@:
276
	push	ecx
277
	mov	ecx, .kNumPosSlotBits
278
	shl	eax, cl
279
	shl	eax, 2
280
	add	eax, .p+.PosSlot*4
281
	call	.RangeDecoderBitTreeDecode
282
	mov	[.rep0], ecx
283
	cmp	ecx, .kStartPosModelIndex
284
	jb	.l6
285
	push	ecx
286
	mov	eax, ecx
287
	and	eax, 1
288
	shr	ecx, 1
289
	or	eax, 2
290
	dec	ecx
291
	shl	eax, cl
292
	mov	[.rep0], eax
293
	pop	edx
294
	cmp	edx, .kEndPosModelIndex
295
	jae	.l5
296
	sub	eax, edx
297
	shl	eax, 2
298
	add	eax, .p + (.SpecPos - 1)*4
299
	call	.RangeDecoderReverseBitTreeDecode
300
	add	[.rep0], ecx
301
	jmp	.l6
302
.l5:
303
	sub	ecx, .kNumAlignBits
304
	call	.RangeDecoderDecodeDirectBits
305
	mov	ecx, .kNumAlignBits
306
	shl	eax, cl
307
	add	[.rep0], eax
308
	mov	eax, .p+.Align_*4
309
	call	.RangeDecoderReverseBitTreeDecode
310
	add	[.rep0], ecx
311
.l6:
312
	pop	ecx
313
	inc	[.rep0]
314
	jz	.main_loop_done
315
.repmovsb:
316
	add	ecx, .kMatchMinLen
317
	push	esi
318
	mov	esi, edi
319
	sub	esi, [.rep0]
320
	rep	movsb
321
	pop	esi
322
	mov	al, [edi-1]
323
	mov	[.previousByte], al
324
	jmp	.main_loop
325
.main_loop_done:
326
	ret
327
 
328
.RangeDecoderBitDecode:
329
; in: eax->prob
330
; out: CF=bit; destroys eax
331
	push	edx
332
	mov	edx, [.range]
333
	shr	edx, .kNumBitModelTotalBits
334
	imul	edx, [eax]
335
	cmp	[.code_], edx
336
	jae	.ae
337
	mov	[.range], edx
338
	mov	edx, .kBitModelTotal
339
	sub	edx, [eax]
340
	shr	edx, .kNumMoveBits
341
	add	[eax], edx
342
	clc
343
.n:
344
	lahf
345
	cmp	[.range], .kTopValue
346
	jae	@f
347
	shl	[.range], 8
348
	shl	[.code_], 8
349
	lodsb
350
	mov	byte [.code_], al
351
@@:
352
	sahf
353
	pop	edx
354
	ret
355
.ae:
356
	sub	[.range], edx
357
	sub	[.code_], edx
358
	mov	edx, [eax]
359
	shr	edx, .kNumMoveBits
360
	sub	[eax], edx
361
	stc
362
	jmp	.n
363
 
364
.RangeDecoderDecodeDirectBits:
365
; in: ecx=numTotalBits
366
; out: eax=result; destroys edx
367
	xor	eax, eax
368
.l:
369
	shr	[.range], 1
370
	shl	eax, 1
371
	mov	edx, [.code_]
372
	sub	edx, [.range]
373
	jb	@f
374
	mov	[.code_], edx
375
	or	eax, 1
376
@@:
377
	cmp	[.range], .kTopValue
378
	jae	@f
379
	shl	[.range], 8
380
	shl	[.code_], 8
381
	push	eax
382
	lodsb
383
	mov	byte [.code_], al
384
	pop	eax
385
@@:
386
	loop	.l
387
	ret
388
 
389
.LzmaLiteralDecode:
390
; in: eax->probs
391
; out: al=byte; destroys edx
392
	push	ecx
393
	mov	ecx, 1
394
@@:
395
	push	eax
396
	lea	eax, [eax+ecx*4]
397
	call	.RangeDecoderBitDecode
398
	pop	eax
399
	adc	cl, cl
400
	jnc	@b
401
.LzmaLiteralDecode.ret:
402
	mov	al, cl
403
	pop	ecx
404
	ret
405
.LzmaLiteralDecodeMatch:
406
; in: eax->probs, dl=matchByte
407
; out: al=byte; destroys edx
408
	push	ecx
409
	mov	ecx, 1
410
.LzmaLiteralDecodeMatch.1:
411
	add	dl, dl
412
	setc	ch
413
	push	eax
414
	lea	eax, [eax+ecx*4+0x100*4]
415
	call	.RangeDecoderBitDecode
416
	pop	eax
417
	adc	cl, cl
418
	jc	.LzmaLiteralDecode.ret
419
	xor	ch, cl
420
	test	ch, 1
421
	mov	ch, 0
422
	jnz	@b
423
	jmp	.LzmaLiteralDecodeMatch.1
424
 
425
.LzmaLenDecode:
426
; in: eax->prob, edx=posState
427
; out: ecx=len
428
	push	eax
429
	add	eax, .LenChoice*4
430
	call	.RangeDecoderBitDecode
431
	pop	eax
432
	jnc	.0
433
	push	eax
434
	add	eax, .LenChoice2*4
435
	call	.RangeDecoderBitDecode
436
	pop	eax
437
	jc	@f
438
	mov	ecx, .kLenNumMidBits
439
	shl	edx, cl
440
	lea	eax, [eax + .LenMid*4 + edx*4]
441
	call	.RangeDecoderBitTreeDecode
442
	add	ecx, .kLenNumLowSymbols
443
	ret
444
@@:
445
	add	eax, .LenHigh*4
446
	mov	ecx, .kLenNumHighBits
447
	call	.RangeDecoderBitTreeDecode
448
	add	ecx, .kLenNumLowSymbols + .kLenNumMidSymbols
449
	ret
450
.0:
451
	mov	ecx, .kLenNumLowBits
452
	shl	edx, cl
453
	lea	eax, [eax + .LenLow*4 + edx*4]
454
.RangeDecoderBitTreeDecode:
455
; in: eax->probs,ecx=numLevels
456
; out: ecx=length; destroys edx
457
	push	ebx
458
	mov	edx, 1
459
	mov	ebx, edx
460
@@:
461
	push	eax
462
	lea	eax, [eax+edx*4]
463
	call	.RangeDecoderBitDecode
464
	pop	eax
465
	adc	dl, dl
466
	add	bl, bl
467
	loop	@b
468
	sub	dl, bl
469
	pop	ebx
470
	mov	ecx, edx
471
	ret
472
.RangeDecoderReverseBitTreeDecode:
473
; in: eax->probs,ecx=numLevels
474
; out: ecx=length; destroys edx
475
	push	ebx ecx
476
	mov	edx, 1
477
	xor	ebx, ebx
478
@@:
479
	push	eax
480
	lea	eax, [eax+edx*4]
481
	call	.RangeDecoderBitDecode
482
	lahf
483
	adc	edx, edx
484
	sahf
485
	rcr	ebx, 1
486
	pop	eax
487
	loop	@b
488
	pop	ecx
489
	rol	ebx, cl
490
	mov	ecx, ebx
491
	pop	ebx
492
	ret
493
 
494
uglobal
495
align 4
496
unpack.p	rd	unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp))
497
unpack.code_	dd	?
498
unpack.range	dd	?
499
unpack.rep0	dd	?
500
unpack.rep1	dd	?
501
unpack.rep2	dd	?
502
unpack.rep3	dd	?
503
unpack.previousByte db	?
504
endg