Subversion Repositories Kolibri OS

Rev

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

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