Subversion Repositories Kolibri OS

Rev

Rev 837 | Details | Compare with Previous | Last modification | View Log | RSS feed

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