Subversion Repositories Kolibri OS

Rev

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

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