Subversion Repositories Kolibri OS

Rev

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