Subversion Repositories Kolibri OS

Rev

Rev 514 | Rev 709 | 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: 593 $
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
169
	mov	edi, .p
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
190
	lea	eax, [.p + .IsMatch*4 + eax + edx*4]
191
	call	.RangeDecoderBitDecode
192
	jc	.1
193
	movzx	eax, [.previousByte]
194
if .literalPosMask
195
	mov	ah, dl
196
	and	ah, .literalPosMask
197
end if
198
	shr	eax, 8-.lc
199
	imul	eax, .LZMA_LIT_SIZE*4
200
	add	eax, .p+.Literal*4
201
	cmp	ebx, .kNumLitStates
202
	jb	.literal
203
	xor	edx, edx
204
	sub	edx, [.rep0]
205
	mov	dl, [edi + edx]
206
	call	.LzmaLiteralDecodeMatch
207
	jmp	@f
208
.literal:
209
	call	.LzmaLiteralDecode
210
@@:
211
	mov	[.previousByte], al
212
	stosb
213
	mov	al, bl
214
	cmp	bl, 4
215
	jb	@f
216
	mov	al, 3
217
	cmp	bl, 10
218
	jb	@f
219
	mov	al, 6
220
@@:	sub	bl, al
221
	jmp	.main_loop
222
.1:
223
	lea	eax, [.p + .IsRep*4 + ebx*4]
224
	call	.RangeDecoderBitDecode
225
	jnc	.10
226
	lea	eax, [.p + .IsRepG0*4 + ebx*4]
227
	call	.RangeDecoderBitDecode
228
	jc	.111
229
	mov	eax, ebx
230
	shl	eax, .kNumPosBitsMax+2
231
	lea	eax, [.p + .IsRep0Long*4 + eax + edx*4]
232
	call	.RangeDecoderBitDecode
233
	jc	.1101
234
	cmp	bl, 7
235
	setae	bl
236
	lea	ebx, [9 + ebx + ebx]
237
	xor	edx, edx
238
	sub	edx, [.rep0]
239
	mov	al, [edi + edx]
240
	stosb
241
	mov	[.previousByte], al
242
	jmp	.main_loop
243
.111:
244
	lea	eax, [.p + .IsRepG1*4 + ebx*4]
245
	call	.RangeDecoderBitDecode
246
	mov	eax, [.rep1]
247
	jnc	.l3
248
.l1:
249
	lea	eax, [.p + .IsRepG2*4 + ebx*4]
250
	call	.RangeDecoderBitDecode
251
	mov	eax, [.rep2]
252
	jnc	.l2
253
	xchg	[.rep3], eax
254
.l2:
255
	push	[.rep1]
256
	pop	[.rep2]
257
.l3:
258
	xchg	eax, [.rep0]
259
	mov	[.rep1], eax
260
.1101:
261
	mov	eax, .p + .RepLencoder*4
262
	call	.LzmaLenDecode
263
	cmp	bl, 7
264
	setc	bl
265
	adc	bl, bl
266
	xor	bl, 3
267
	add	bl, 8
268
	jmp	.repmovsb
269
.10:
270
	mov	eax, [.rep0]
271
	xchg	eax, [.rep1]
272
	xchg	eax, [.rep2]
273
	xchg	eax, [.rep3]
274
	cmp	bl, 7
275
	setc	bl
276
	adc	bl, bl
277
	xor	bl, 3
278
	add	bl, 7
279
	mov	eax, .p + .Lencoder*4
280
	call	.LzmaLenDecode
281
	mov	eax, .kNumLenToPosStates-1
282
	cmp	eax, ecx
283
	jb	@f
284
	mov	eax, ecx
285
@@:
286
	push	ecx
287
	mov	ecx, .kNumPosSlotBits
288
	shl	eax, cl
289
	shl	eax, 2
290
	add	eax, .p+.PosSlot*4
291
	call	.RangeDecoderBitTreeDecode
292
	mov	[.rep0], ecx
293
	cmp	ecx, .kStartPosModelIndex
294
	jb	.l6
295
	push	ecx
296
	mov	eax, ecx
297
	and	eax, 1
298
	shr	ecx, 1
299
	or	eax, 2
300
	dec	ecx
301
	shl	eax, cl
302
	mov	[.rep0], eax
303
	pop	edx
304
	cmp	edx, .kEndPosModelIndex
305
	jae	.l5
306
	sub	eax, edx
307
	shl	eax, 2
308
	add	eax, .p + (.SpecPos - 1)*4
309
	call	.RangeDecoderReverseBitTreeDecode
310
	add	[.rep0], ecx
311
	jmp	.l6
312
.l5:
313
	sub	ecx, .kNumAlignBits
314
	call	.RangeDecoderDecodeDirectBits
315
	mov	ecx, .kNumAlignBits
316
	shl	eax, cl
317
	add	[.rep0], eax
318
	mov	eax, .p+.Align_*4
319
	call	.RangeDecoderReverseBitTreeDecode
320
	add	[.rep0], ecx
321
.l6:
322
	pop	ecx
323
	inc	[.rep0]
324
	jz	.main_loop_done
325
.repmovsb:
326
	add	ecx, .kMatchMinLen
327
	push	esi
328
	mov	esi, edi
329
	sub	esi, [.rep0]
330
	rep	movsb
331
	pop	esi
332
	mov	al, [edi-1]
333
	mov	[.previousByte], al
334
	jmp	.main_loop
335
.main_loop_done:
336
	ret
337
 
338
.RangeDecoderBitDecode:
339
; in: eax->prob
340
; out: CF=bit; destroys eax
341
	push	edx
342
	mov	edx, [.range]
343
	shr	edx, .kNumBitModelTotalBits
344
	imul	edx, [eax]
345
	cmp	[.code_], edx
346
	jae	.ae
347
	mov	[.range], edx
348
	mov	edx, .kBitModelTotal
349
	sub	edx, [eax]
350
	shr	edx, .kNumMoveBits
351
	add	[eax], edx
352
	clc
353
.n:
354
	lahf
355
	cmp	[.range], .kTopValue
356
	jae	@f
357
	shl	[.range], 8
358
	shl	[.code_], 8
359
	lodsb
360
	mov	byte [.code_], al
361
@@:
362
	sahf
363
	pop	edx
364
	ret
365
.ae:
366
	sub	[.range], edx
367
	sub	[.code_], edx
368
	mov	edx, [eax]
369
	shr	edx, .kNumMoveBits
370
	sub	[eax], edx
371
	stc
372
	jmp	.n
373
 
374
.RangeDecoderDecodeDirectBits:
375
; in: ecx=numTotalBits
376
; out: eax=result; destroys edx
377
	xor	eax, eax
378
.l:
379
	shr	[.range], 1
380
	shl	eax, 1
381
	mov	edx, [.code_]
382
	sub	edx, [.range]
383
	jb	@f
384
	mov	[.code_], edx
385
	or	eax, 1
386
@@:
387
	cmp	[.range], .kTopValue
388
	jae	@f
389
	shl	[.range], 8
390
	shl	[.code_], 8
391
	push	eax
392
	lodsb
393
	mov	byte [.code_], al
394
	pop	eax
395
@@:
396
	loop	.l
397
	ret
398
 
399
.LzmaLiteralDecode:
400
; in: eax->probs
401
; out: al=byte; destroys edx
402
	push	ecx
403
	mov	ecx, 1
404
@@:
405
	push	eax
406
	lea	eax, [eax+ecx*4]
407
	call	.RangeDecoderBitDecode
408
	pop	eax
409
	adc	cl, cl
410
	jnc	@b
411
.LzmaLiteralDecode.ret:
412
	mov	al, cl
413
	pop	ecx
414
	ret
415
.LzmaLiteralDecodeMatch:
416
; in: eax->probs, dl=matchByte
417
; out: al=byte; destroys edx
418
	push	ecx
419
	mov	ecx, 1
420
.LzmaLiteralDecodeMatch.1:
421
	add	dl, dl
422
	setc	ch
423
	push	eax
424
	lea	eax, [eax+ecx*4+0x100*4]
425
	call	.RangeDecoderBitDecode
426
	pop	eax
427
	adc	cl, cl
428
	jc	.LzmaLiteralDecode.ret
429
	xor	ch, cl
430
	test	ch, 1
431
	mov	ch, 0
432
	jnz	@b
433
	jmp	.LzmaLiteralDecodeMatch.1
434
 
435
.LzmaLenDecode:
436
; in: eax->prob, edx=posState
437
; out: ecx=len
438
	push	eax
439
	add	eax, .LenChoice*4
440
	call	.RangeDecoderBitDecode
441
	pop	eax
442
	jnc	.0
443
	push	eax
444
	add	eax, .LenChoice2*4
445
	call	.RangeDecoderBitDecode
446
	pop	eax
447
	jc	@f
448
	mov	ecx, .kLenNumMidBits
449
	shl	edx, cl
450
	lea	eax, [eax + .LenMid*4 + edx*4]
451
	call	.RangeDecoderBitTreeDecode
452
	add	ecx, .kLenNumLowSymbols
453
	ret
454
@@:
455
	add	eax, .LenHigh*4
456
	mov	ecx, .kLenNumHighBits
457
	call	.RangeDecoderBitTreeDecode
458
	add	ecx, .kLenNumLowSymbols + .kLenNumMidSymbols
459
	ret
460
.0:
461
	mov	ecx, .kLenNumLowBits
462
	shl	edx, cl
463
	lea	eax, [eax + .LenLow*4 + edx*4]
464
.RangeDecoderBitTreeDecode:
465
; in: eax->probs,ecx=numLevels
466
; out: ecx=length; destroys edx
467
	push	ebx
468
	mov	edx, 1
469
	mov	ebx, edx
470
@@:
471
	push	eax
472
	lea	eax, [eax+edx*4]
473
	call	.RangeDecoderBitDecode
474
	pop	eax
475
	adc	dl, dl
476
	add	bl, bl
477
	loop	@b
478
	sub	dl, bl
479
	pop	ebx
480
	mov	ecx, edx
481
	ret
482
.RangeDecoderReverseBitTreeDecode:
483
; in: eax->probs,ecx=numLevels
484
; out: ecx=length; destroys edx
485
	push	ebx ecx
486
	mov	edx, 1
487
	xor	ebx, ebx
488
@@:
489
	push	eax
490
	lea	eax, [eax+edx*4]
491
	call	.RangeDecoderBitDecode
492
	lahf
493
	adc	edx, edx
494
	sahf
495
	rcr	ebx, 1
496
	pop	eax
497
	loop	@b
498
	pop	ecx
499
	rol	ebx, cl
500
	mov	ecx, ebx
501
	pop	ebx
502
	ret
503
 
504
uglobal
505
align 4
506
unpack.p	rd	unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp))
507
unpack.code_	dd	?
508
unpack.range	dd	?
509
unpack.rep0	dd	?
510
unpack.rep1	dd	?
511
unpack.rep2	dd	?
512
unpack.rep3	dd	?
513
unpack.previousByte db	?
514
endg