Subversion Repositories Kolibri OS

Rev

Rev 467 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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