Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
589 diamond 1
; PPMD decoder, ported from C++ sources of 7-Zip (c) Igor Pavlov
2
; C++ code is based on Dmitry Shkarin's PPMdH code
3
uglobal
4
ppmd_decoder.NS2Indx    rb      256
5
ppmd_decoder.NS2BSIndx  rb      256
6
ppmd_decoder.HB2Flag    rb      256
7
ppmd_decoder.Indx2Units rb      ppmd_decoder.N_INDEXES
8
ppmd_decoder.Units2Indx rb      128
9
endg
10
 
11
iglobal
12
label ppmd_decoder.InitBinEsc word
13
        dw      0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051
14
ppmd_decoder.ExpEscape db 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2
15
endg
16
 
17
init_ppmd:
18
; NS2Indx table
19
        mov     edi, ppmd_decoder.NS2Indx
20
        xor     eax, eax
21
        stosb
22
        inc     eax
23
        stosb
24
        inc     eax
25
        stosb
26
        mov     edx, 3-256
27
@@:
28
        lea     ecx, [eax-1]
29
        inc     eax
30
        add     edx, ecx
31
        jc      @f
32
        rep     stosb
33
        jmp     @b
34
@@:
35
        sub     ecx, edx
36
        rep     stosb
37
; NS2BSIndx table
38
        xor     eax, eax
39
        stosb
40
        add     al, 2
41
        stosb
42
        add     al, 2
43
        mov     cl, 9
44
        rep     stosb
45
        add     al, 2
46
        mov     cl, 256-11
47
        rep     stosb
48
; HB2Flag table
49
        mov     cl, 0x40/4
50
        xor     eax, eax
51
        rep     stosd
52
        mov     al, 8
53
        mov     cl, 0x100-0x40
54
        rep     stosb
55
; Indx2Units table
56
        mov     eax, 0x04030201
57
        stosd
58
        mov     eax, 0x0C0A0806
59
        stosd
60
        mov     eax, 0x1815120F
61
        stosd
62
        mov     al, 0x1C
63
@@:
64
        stosb
65
        add     al, 4
66
        cmp     al, 0x80
67
        jbe     @b
68
; Units2Indx table
69
        xor     eax, eax
70
        xor     edx, edx
71
        inc     edx
72
        xor     ecx, ecx
73
@@:
74
        cmp     [ppmd_decoder.Indx2Units+eax], dl
75
        adc     al, 0
76
        stosb
77
        inc     edx
78
        cmp     dl, 0x80
79
        jbe     @b
80
        ret
81
 
82
ppmd_decoder:
83
virtual at 0
84
; base is standard structure
85
.outStream      rb      streamInfo.size
86
.inStream       dd      ?
87
 
88
; RangeDecoder data
89
.inLen          dd      ?
90
.inPtr          dd      ?
91
.code           dd      ?
92
.range          dd      ?
93
 
94
.outSize        dd      ?       ; number of bytes rest for output
95
 
96
; PPMD data
97
.order          db      ?
98
.GlueCount      db      ?
99
.bInited        db      ?
100
                rb      1
101
.usedMemorySize dd      ?
102
 
103
; CSubAllocator constants
104
.N1 = 4
105
.N2 = 4
106
.N3 = 4
107
.N4 = (128+3-1*.N1-2*.N2-3*.N3)/4
108
.UNIT_SIZE = 12
109
.N_INDEXES = .N1+.N2+.N3+.N4
110
.kExtraSize = .UNIT_SIZE*3
111
.kMaxMemBlockSize = 0xFFFFFFFF - .kExtraSize
112
 
113
; CSubAllocator data
114
.HeapStart      dd      ?
115
.LoUnit         dd      ?
116
.HiUnit         dd      ?
117
.pText          dd      ?
118
.UnitsStart     dd      ?
119
.FreeList       rd      .N_INDEXES
120
 
121
; Context constants
122
.INT_BITS = 7
123
.PERIOD_BITS = 7
124
.TOT_BITS = .INT_BITS + .PERIOD_BITS
125
.INTERVAL = 1 shl .INT_BITS
126
.BIN_SCALE = 1 shl .TOT_BITS
127
.MAX_FREQ = 124
128
 
129
.kMaxOrderCompress = 32
130
.MAX_O = 255
131
 
132
; CDecodeInfo (inherits from CInfo) data
133
; SEE2_CONTEXT is 4 bytes long
134
.SEE2Cont       rd      25*16
135
.DummySEE2Cont  dd      ?
136
.MinContext     dd      ?
137
.MaxContext     dd      ?
138
.FoundState     dd      ?       ; found next state transition
139
.NumMasked      dd      ?
140
.InitEsc        dd      ?
141
.OrderFall      dd      ?
142
.RunLength      dd      ?
143
.InitRL         dd      ?
144
.CharMask       rb      256
145
.EscCount       db      ?
146
.PrintCount     db      ?
147
.PrevSuccess    db      ?
148
.HiBitsFlag     db      ?
149
.BinSumm        rw      128*64
150
 
151
.basesize = $
152
.Base:
153
;               rb      .kExtraSize + [.usedMemorySize]
154
end virtual
155
 
156
.init:
157
        mov     eax, [eax+.inStream]
158
        call    fillBuf
159
        mov     esi, [eax+streamInfo.bufPtr]
160
        mov     eax, [eax+streamInfo.bufDataLen]
161
        sub     eax, 5
162
        jb      return.err
163
        mov     [ebp+.inLen], eax
164
        inc     esi
165
        lodsd
166
        mov     [ebp+.inPtr], esi
167
        bswap   eax
168
        mov     [ebp+.code], eax
169
        or      [ebp+.range], -1
170
        mov     [ebp+.bInited], 1
171
        call    .StartModelRare
172
        mov     eax, ebp
173
        jmp     .mainloop
174
 
175
.fillBuf:
176
        mov     ebp, eax
177
        mov     [eax+.outSize], ecx
178
        cmp     [eax+.bInited], 0
179
        jz      .init
180
.mainloop:
181
        sub     [ebp+.outSize], 1
182
        js      .mainloopdone
183
;        cmp     edi, 0xde070+0x18
184
;        jnz     @f
185
;        int3
186
;@@:
187
        call    .DecodeSymbol
188
        jmp     .mainloop
189
.mainloopdone:
190
        popad
191
        ret
192
 
193
.GetBinSumm:
194
; CInfo::GetBinSumm(ebx=rs, ecx=numStates)
195
        movzx   eax, [ebp+.PrevSuccess]
196
        movzx   edx, [.NS2BSIndx+ecx-1]
197
        add     eax, edx
198
        mov     edx, [ebp+.FoundState]
199
        movzx   edx, byte [edx]
200
        movzx   edx, [.HB2Flag+edx]
201
        mov     [ebp+.HiBitsFlag], dl
202
        add     eax, edx
203
        movzx   edx, byte [ebx]
204
        movzx   edx, [.HB2Flag+edx]
205
        lea     eax, [eax+edx*2]
206
        mov     edx, [ebp+.RunLength]
207
        shr     edx, 26
208
        and     edx, 0x20
209
        add     eax, edx
210
        movzx   edx, byte [ebx+1]
211
        shl     edx, 6
212
        add     eax, edx
213
        lea     ecx, [ebp+.BinSumm+eax*2-2*64]
214
        ret
215
 
216
.StartModelRare:
217
; CInfo::StartModelRare(.order)
218
        mov     [ebp+.EscCount], 1
219
        mov     [ebp+.PrintCount], 1
220
; N.B.
221
; 1. Original code has some handling of [.order]<2, but this handling is incorrect
222
;    and causes exception (access violation).
223
; 2. 7-Zip never generates archives with [.order]<2 due to input preprocessing
224
;    (for PPMd method in switch -mo= archiver checks that 2 <= n <= 32).
225
; 3. If manually created archive says [.order]<2, the exception will be generated
226
;    in StartModelRare, but it will be handled in Code() resulting in "data error".
227
        cmp     [ebp+.order], 2
228
        jb      return.err
229
        mov     byte [ebp+.DummySEE2Cont+2], .PERIOD_BITS
230
 
231
.RestartModelRare:
232
; CInfo::RestartModelRare(void)
233
        push    edi
234
        lea     edi, [ebp+.CharMask]
235
        xor     eax, eax
236
        push    0x40
237
        pop     ecx
238
        rep     stosd
239
; CSubAllocator::InitSubAllocator start
240
        mov     [ebp+.GlueCount], al
241
        lea     edi, [ebp+.FreeList]
242
        mov     cl, .N_INDEXES
243
        rep     stosd
244
        mov     ebx, [ebp+.HeapStart]
245
        mov     [ebp+.pText], ebx
246
        add     ebx, [ebp+.usedMemorySize]
247
        mov     [ebp+.HiUnit], ebx
248
        mov     eax, [ebp+.usedMemorySize]
249
        xor     edx, edx
250
        mov     cl, 8*.UNIT_SIZE
251
        div     ecx
252
        imul    eax, 7*.UNIT_SIZE
253
        sub     ebx, eax
254
        mov     [ebp+.LoUnit], ebx
255
        mov     [ebp+.UnitsStart], ebx
256
; CSubAllocator::InitSubAllocator end
257
        pop     edi
258
        movzx   eax, [ebp+.order]
259
        cmp     al, 12
260
        jb      @f
261
        mov     al, 12
262
@@:
263
        neg     eax
264
        dec     eax
265
        mov     [ebp+.InitRL], eax
266
        mov     [ebp+.RunLength], eax
267
        call    .AllocContext
268
        mov     [ebp+.MinContext], eax
269
        mov     [ebp+.MaxContext], eax
270
        and     dword [eax+8], 0
271
        mov     esi, eax
272
        movzx   edx, [ebp+.order]
273
        mov     [ebp+.OrderFall], edx
274
        mov     dword [eax], 257*10000h+256
275
        mov     ecx, 256/2
276
        call    .AllocUnits
277
        mov     [ebp+.FoundState], eax
278
        mov     [esi+4], eax
279
        push    edi
280
        mov     edi, eax
281
        xor     eax, eax
282
        mov     [ebp+.PrevSuccess], al
283
@@:
284
        stosb
285
        mov     byte [edi], 1
286
        and     dword [edi+1], 0
287
        add     edi, 5
288
        inc     al
289
        jnz     @b
290
        lea     edi, [ebp+.BinSumm]
291
        push    2
292
        pop     ecx
293
.rmr1:
294
        mov     esi, .InitBinEsc
295
@@:
296
        lodsw
297
        xor     edx, edx
298
        div     ecx
299
        sub     eax, .BIN_SCALE
300
        neg     eax
301
        mov     [edi+2*8], ax
302
        mov     [edi+2*16], ax
303
        mov     [edi+2*24], ax
304
        mov     [edi+2*32], ax
305
        mov     [edi+2*40], ax
306
        mov     [edi+2*48], ax
307
        mov     [edi+2*56], ax
308
        stosw
309
        cmp     esi, .InitBinEsc+2*8
310
        jb      @b
311
        add     edi, 128-16
312
        inc     ecx
313
        cmp     ecx, 128+2
314
        jb      .rmr1
315
        lea     edi, [ebp+.SEE2Cont]
316
        mov     eax, (10 shl (.PERIOD_BITS-4)) + ((.PERIOD_BITS-4) shl 16) + (4 shl 24)
317
        push    25
318
        pop     edx
319
@@:
320
        push    16
321
        pop     ecx
322
        rep     stosd
323
        add     ax, 5 shl (.PERIOD_BITS-4)
324
        dec     edx
325
        jnz     @b
326
        pop     edi
327
        ret
328
 
329
.CreateSuccessors:
330
; CInfo::CreateSuccessors(bool al=skip,STATE* esi=p1)
331
        push    ebx edi
332
        mov     ebx, [ebp+.MinContext]  ; ebx=pc
333
        mov     ecx, [ebp+.FoundState]
334
        mov     ecx, [ecx+2]            ; ecx=UpBranch
335
        sub     esp, .MAX_O*4           ; esp=ps
336
        mov     edi, esp                ; edi=pps
337
        test    al, al
338
        jnz     @f
339
        mov     eax, [ebp+.FoundState]
340
        stosd
341
        cmp     dword [ebx+8], 0
342
        jz      .csnoloop
343
@@:
344
        test    esi, esi
345
        jz      .csloopstart
346
        mov     edx, esi                ; edx=p
347
        mov     ebx, [ebx+8]
348
        jmp     .csloopentry
349
.csloopstart:
350
        mov     ebx, [ebx+8]
351
        lea     edx, [ebx+2]
352
        cmp     word [ebx], 1
353
        jz      .csloopentry
354
        mov     edx, [ebx+4]
355
        mov     eax, [ebp+.FoundState]
356
        sub     edx, 6
357
        mov     al, [eax]
358
@@:
359
        add     edx, 6
360
        cmp     al, [edx]
361
        jnz     @b
362
.csloopentry:
363
        cmp     ecx, [edx+2]
364
        jz      @f
365
        mov     ebx, [edx+2]
366
        jmp     .csnoloop
367
@@:
368
        mov     [edi], edx
369
        add     edi, 4
370
        cmp     dword [ebx+8], 0
371
        jnz     .csloopstart
372
.csnoloop:
373
        cmp     edi, esp
374
        jz      .csr
375
        push    eax
376
        push    eax
377
        mov     al, [ecx]
378
        mov     [esp], al
379
        add     ecx, 1
380
        mov     [esp+2], ecx
381
        mov     ah, [ebx+3]
382
        cmp     word [ebx], 1
383
        jz      .cs2
384
        mov     edx, [ebx+4]
385
        sub     edx, 6
386
@@:
387
        add     edx, 6
388
        cmp     [edx], al
389
        jnz     @b
390
        movzx   edx, byte [edx+1]
391
        sub     edx, 1          ; edx=cf
392
        movzx   ecx, word [ebx+2]
393
        movzx   eax, word [ebx]
394
        sub     ecx, eax
395
        sub     ecx, edx        ; ecx=s0
396
        lea     eax, [edx+edx]
397
        cmp     eax, ecx
398
        ja      .cs0
399
        lea     eax, [edx*5]
400
        cmp     eax, ecx
401
        seta    ah
402
        jmp     .cs1
403
.cs0:
404
        lea     eax, [eax+ecx*2]
405
        lea     eax, [eax+ecx-1]
406
        add     ecx, ecx
407
        xor     edx, edx
408
        div     ecx
409
        mov     ah, al
410
.cs1:
411
        add     ah, 1
412
.cs2:
413
        mov     [esp+1], ah
414
        sub     edi, 8
415
.cs3:
416
; PPM_CONTEXT::createChild(this=ebx,pStats=[edi+4],FirstState=esp) begin
417
        call    .AllocContext
418
        test    eax, eax
419
        jz      .csr0
420
        mov     word [eax], 1
421
        mov     dx, [esp]
422
        mov     [eax+2], dx
423
        mov     edx, [esp+2]
424
        mov     [eax+4], edx
425
        mov     [eax+8], ebx
426
        mov     edx, [edi+4]
427
        mov     [edx+2], eax
428
; PPM_CONTEXT::createChild end
429
        mov     ebx, eax
430
        sub     edi, 4
431
        cmp     edi, esp
432
        jnz     .cs3
433
        pop     eax eax
434
.csr:
435
        mov     eax, ebx
436
@@:
437
        add     esp, .MAX_O*4
438
        pop     edi ebx
439
        ret
440
.csr0:
441
        pop     eax eax
442
        xor     eax, eax
443
        jmp     @b
444
 
445
; CInfo::UpdateModel(void)
446
.UpdateModel:
447
        mov     ebx, [ebp+.FoundState]
448
        xor     esi, esi                ; esi=p
449
        movzx   eax, word [ebx]
450
        mov     ebx, [ebx+2]            ; ebx=fs.Successor
451
        push    eax
452
        cmp     ah, .MAX_FREQ/4
453
        jae     .um2
454
        mov     eax, [ebp+.MinContext]
455
        mov     eax, [eax+8]
456
        test    eax, eax
457
        jz      .um2
458
        cmp     word [eax], 1
459
        jz      .um1
460
        push    eax
461
        mov     esi, [eax+4]
462
        mov     al, [esp+4]
463
        cmp     al, [esi]
464
        jz      .um0
465
@@:
466
        add     esi, 6
467
        cmp     al, [esi]
468
        jnz     @b
469
        mov     al, [esi+1]
470
        cmp     al, [esi-6+1]
471
        jb      @f
472
        mov     eax, [esi]
473
        xchg    [esi-6], eax
474
        mov     [esi], eax
475
        mov     ax, [esi+4]
476
        xchg    [esi-6+4], ax
477
        mov     [esi+4], ax
478
        sub     esi, 6
479
@@:
480
.um0:
481
        pop     eax
482
        cmp     byte [esi+1], .MAX_FREQ-9
483
        jae     @f
484
        add     byte [esi+1], 2
485
        add     word [eax+2], 2
486
@@:
487
        jmp     .um2
488
.um1:
489
        lea     esi, [eax+2]
490
        cmp     byte [esi+1], 32
491
        adc     byte [esi+1], 0
492
.um2:
493
        cmp     [ebp+.OrderFall], 0
494
        jnz     .um3
495
        pop     eax
496
        mov     al, 1
497
        call    .CreateSuccessors
498
        mov     [ebp+.MinContext], eax
499
        mov     [ebp+.MaxContext], eax
500
        mov     edx, [ebp+.FoundState]
501
        mov     [edx+2], eax
502
        test    eax, eax
503
        jz      .RestartModel
504
        ret
505
.um3:
506
        mov     edx, [ebp+.pText]
507
        mov     al, [esp]
508
        mov     [edx], al
509
        add     edx, 1          ; edx=Successor
510
        mov     [ebp+.pText], edx
511
        cmp     edx, [ebp+.UnitsStart]
512
        jae     .RestartModelPop
513
        test    ebx, ebx
514
        jz      .um4
515
        cmp     ebx, [ebp+.pText]
516
        ja      @f
517
        push    edx
518
        xor     eax, eax
519
        call    .CreateSuccessors
520
        pop     edx
521
        mov     ebx, eax
522
        test    eax, eax
523
        jz      .RestartModelPop
524
@@:
525
        sub     [ebp+.OrderFall], 1
526
        jnz     @f
527
        mov     edx, ebx
528
        xor     ecx, ecx
529
        mov     eax, [ebp+.MinContext]
530
        cmp     eax, [ebp+.MaxContext]
531
        setnz   cl
532
        sub     [ebp+.pText], ecx
533
@@:
534
        jmp     .um5
535
.um4:
536
        mov     eax, [ebp+.FoundState]
537
        mov     [eax+2], edx
538
        mov     ebx, [ebp+.MinContext]
539
.um5:
540
        mov     eax, [ebp+.MinContext]
541
        movzx   ecx, word [eax] ; ecx=ns
542
        movzx   eax, word [eax+2]
543
        sub     eax, ecx
544
        push    eax
545
        movzx   eax, byte [esp+5]
546
        sub     eax, 1
547
        sub     [esp], eax      ; [esp]=s0
548
        mov     esi, [ebp+.MaxContext]  ; ebx=pc
549
        cmp     esi, [ebp+.MinContext]
550
        jz      .um12
551
.um6:
552
        movzx   eax, word [esi]
553
        cmp     eax, 1
554
        jz      .um8
555
        push    eax
556
        shr     eax, 1
557
        jc      .um7
558
        push    esi
559
        mov     esi, [esi+4]
560
        call    .ExpandUnits
561
        pop     esi
562
        mov     [esi+4], eax
563
        test    eax, eax
564
        jz      .RestartModelPop3
565
.um7:
566
        pop     eax
567
        add     eax, eax
568
        cmp     eax, ecx
569
        adc     word [esi+2], 0
570
        add     eax, eax
571
        cmp     eax, ecx
572
        ja      @f
573
        lea     eax, [eax+eax+1]
574
        cmp     word [esi+2], ax
575
        ja      @f
576
        add     word [esi+2], 2
577
@@:
578
        push    edx
579
        jmp     .um9
580
.um8:
581
        push    edx ecx
582
        mov     ecx, 1
583
        call    .AllocUnits
584
        pop     ecx
585
        test    eax, eax
586
        jz      .RestartModelPop3
587
        mov     dx, [esi+2]
588
        mov     [eax], dx
589
        mov     edx, [esi+4]
590
        mov     [eax+2], edx
591
        mov     [esi+4], eax
592
        movzx   edx, byte [eax+1]
593
        add     edx, edx
594
        cmp     edx, (.MAX_FREQ/4-1)*2
595
        jb      @f
596
        mov     edx, .MAX_FREQ-4
597
@@:
598
        mov     [eax+1], dl
599
        add     edx, [ebp+.InitEsc]
600
        cmp     ecx, 4
601
        sbb     edx, -1
602
        mov     [esi+2], dx
603
.um9:
604
        movzx   edx, word [esi+2]
605
        mov     eax, [esp+4]
606
        push    ecx
607
        lea     ecx, [eax+edx]  ; ecx=sf
608
        add     edx, 6
609
        movzx   eax, byte [esp+13]
610
        add     eax, eax
611
        imul    eax, edx        ; eax=cf
612
        lea     edx, [ecx*3]
613
        add     edx, edx
614
        cmp     eax, edx
615
        jae     .um10
616
        mov     edx, 1
617
        cmp     ecx, eax
618
        adc     edx, 0
619
        shl     ecx, 2
620
        add     eax, 1
621
        cmp     ecx, eax
622
        adc     edx, 0
623
        add     word [esi+2], 3
624
        jmp     .um11
625
.um10:
626
        lea     ecx, [ecx*3]
627
        lea     edx, [ecx*3]
628
        add     eax, 1
629
        push    4
630
        cmp     edx, eax
631
        adc     dword [esp], 0
632
        add     edx, ecx
633
        cmp     edx, eax
634
        adc     dword [esp], 0
635
        add     edx, ecx
636
        cmp     edx, eax
637
        adc     dword [esp], 0
638
        pop     edx
639
        add     [esi+2], dx
640
.um11:
641
        movzx   eax, word [esi]
642
        lea     eax, [eax*3]
643
        add     eax, eax
644
        add     eax, [esi+4]
645
        mov     ecx, [esp+4]
646
        mov     [eax+2], ecx
647
        mov     cl, [esp+12]
648
        mov     [eax], cl
649
        mov     [eax+1], dl
650
        add     word [esi], 1
651
        pop     ecx edx
652
        mov     esi, [esi+8]
653
        cmp     esi, [ebp+.MinContext]
654
        jnz     .um6
655
.um12:
656
        pop     eax
657
        pop     eax
658
        mov     [ebp+.MinContext], ebx
659
        mov     [ebp+.MaxContext], ebx
660
        ret
661
.RestartModelPop3:
662
        pop     eax
663
        pop     eax
664
.RestartModelPop:
665
        pop     eax
666
.RestartModel:
667
        call    .RestartModelRare
668
        mov     [ebp+.EscCount], 0
669
        mov     [ebp+.PrintCount], 0xFF
670
        ret
671
 
672
.rescale:
673
        mov     esi, [ebp+.MinContext]
674
        movzx   ecx, word [esi]
675
        push    ecx     ; [esp]=OldNS
676
        sub     ecx, 1
677
        mov     ebx, [ebp+.FoundState]
678
        cmp     ebx, [esi+4]
679
        jz      .r1
680
.r0:
681
        mov     ax, [ebx]
682
        xchg    [ebx-6], ax
683
        mov     [ebx], ax
684
        mov     eax, [ebx+2]
685
        xchg    [ebx-6+2], eax
686
        mov     [ebx+2], eax
687
        sub     ebx, 6
688
        cmp     ebx, [esi+4]
689
        jnz     .r0
690
.r1:
691
        add     byte [ebx+1], 4
692
        add     word [esi+2], 4
693
        movzx   eax, byte [ebx+1]
694
        movzx   edx, word [esi+2]
695
        sub     edx, eax        ; edx=EscFreq
696
        cmp     [ebp+.OrderFall], 1
697
        sbb     eax, -1
698
        shr     eax, 1
699
        mov     [ebx+1], al
700
        mov     [esi+2], ax
701
.r2:
702
        add     ebx, 6
703
        movzx   eax, byte [ebx+1]
704
        sub     edx, eax
705
        cmp     [ebp+.OrderFall], 1
706
        sbb     eax, -1
707
        shr     eax, 1
708
        mov     [ebx+1], al
709
        add     [esi+2], ax
710
        cmp     al, [ebx-6+1]
711
        jbe     .r3
712
        push    ecx
713
        push    ebx
714
        push    dword [ebx]
715
        push    word [ebx+4]
716
@@:
717
        mov     ecx, [ebx-6]
718
        mov     [ebx], ecx
719
        mov     cx, [ebx-6+4]
720
        mov     [ebx+4], cx
721
        sub     ebx, 6
722
        cmp     ebx, [esi+4]
723
        jz      @f
724
        cmp     al, [ebx-6+1]
725
        ja      @b
726
@@:
727
        pop     word [ebx+4]
728
        pop     dword [ebx]
729
        pop     ebx
730
        pop     ecx
731
.r3:
732
        sub     ecx, 1
733
        jnz     .r2
734
        cmp     byte [ebx+1], 0
735
        jnz     .r4
736
@@:
737
        add     ecx, 1
738
        sub     ebx, 6
739
        cmp     byte [ebx+1], 0
740
        jz      @b
741
        add     edx, ecx
742
        sub     word [esi], cx
743
        cmp     word [esi], 1
744
        jnz     .r4
745
        pop     ebx
746
        mov     eax, [esi+4]
747
        movzx   ecx, word [eax+4]
748
        push    ecx
749
        push    dword [eax]
750
        movzx   eax, byte [eax+1]
751
@@:
752
        add     eax, 1
753
        shr     eax, 1
754
        shr     edx, 1
755
        cmp     edx, 1
756
        ja      @b
757
        mov     [esp+1], al
758
        add     ebx, 1
759
        shr     ebx, 1
760
        mov     eax, [esi+4]
761
        call    .FreeUnits
762
        lea     ebx, [esi+2]
763
        mov     [ebp+.FoundState], ebx
764
        pop     dword [ebx]
765
        pop     eax
766
        mov     [ebx+4], ax
767
        ret
768
.r4:
769
        add     edx, 1
770
        shr     edx, 1
771
        add     [esi+2], dx
772
        pop     ebx
773
        add     ebx, 1
774
        shr     ebx, 1
775
        movzx   ecx, word [esi]
776
        add     ecx, 1
777
        shr     ecx, 1
778
        cmp     ebx, ecx
779
        jz      @f
780
        mov     eax, [esi+4]
781
        call    .ShrinkUnits
782
        mov     [esi+4], eax
783
@@:
784
        mov     eax, [esi+4]
785
        mov     [ebp+.FoundState], eax
786
        ret
787
 
788
.DecodeSymbol:
789
; CDecodeInfo::DecodeSymbol
790
        mov     esi, [ebp+.MinContext]
791
        cmp     word [esi], 1
792
        jz      .binsymbol
793
; CDecodeInfo::DecodeSymbol1 start
794
        mov     ebx, [esi+4]    ; state
795
        movzx   ecx, word [esi+2]
796
        mov     eax, [ebp+.range]
797
        xor     edx, edx
798
        div     ecx
799
        mov     [ebp+.range], eax
800
        mov     ecx, eax
801
        mov     eax, [ebp+.code]
802
        xor     edx, edx
803
        div     ecx
804
        movzx   edx, byte [ebx+1]
805
        cmp     eax, edx
806
        jae     .ds0
807
        push    edx
808
        add     edx, edx
809
        cmp     dx, [esi+2]
810
        pop     edx
811
        seta    [ebp+.PrevSuccess]
812
        movzx   eax, [ebp+.PrevSuccess]
813
        add     [ebp+.RunLength], eax
814
        xor     eax, eax
815
        call    .RangeDecoder.Decode
816
        mov     [ebp+.FoundState], ebx
817
        add     edx, 4
818
        mov     [ebx+1], dl
819
        add     word [esi+2], 4
820
        cmp     edx, .MAX_FREQ
821
        jbe     @f
822
        call    .rescale
823
@@:
824
        jmp     .dscmn
825
.ds0:
826
        mov     [ebp+.PrevSuccess], 0
827
        movzx   ecx, word [esi]
828
        sub     ecx, 1
829
        push    eax
830
.ds1:
831
        add     ebx, 6
832
        movzx   eax, byte [ebx+1]
833
        add     edx, eax
834
        cmp     edx, [esp]
835
        ja      .ds2
836
        sub     ecx, 1
837
        jnz     .ds1
838
        pop     eax
839
        mov     eax, [ebp+.FoundState]
840
        movzx   eax, byte [eax]
841
        mov     al, [.HB2Flag+eax]
842
        mov     [ebp+.HiBitsFlag], al
843
        mov     eax, edx
844
        movzx   edx, word [esi+2]
845
        sub     edx, eax
846
        call    .RangeDecoder.Decode
847
        mov     al, [ebp+.EscCount]
848
        movzx   edx, byte [ebx]
849
        mov     [ebp+.CharMask+edx], al
850
        movzx   ecx, word [esi]
851
        mov     [ebp+.NumMasked], ecx
852
        sub     ecx, 1
853
@@:
854
        sub     ebx, 6
855
        movzx   edx, byte [ebx]
856
        mov     [ebp+.CharMask+edx], al
857
        sub     ecx, 1
858
        jnz     @b
859
        mov     [ebp+.FoundState], ecx
860
        jmp     .dscmn
861
.ds2:
862
        pop     eax
863
        mov     eax, edx
864
        movzx   edx, byte [ebx+1]
865
        sub     eax, edx
866
        call    .RangeDecoder.Decode
867
.update1:
868
        mov     [ebp+.FoundState], ebx
869
        add     byte [ebx+1], 4
870
        add     word [esi+2], 4
871
        mov     al, [ebx+1]
872
        cmp     al, [ebx-6+1]
873
        jbe     @f
874
        mov     eax, [ebx]
875
        xchg    eax, [ebx-6]
876
        mov     [ebx], eax
877
        mov     ax, [ebx+4]
878
        xchg    ax, [ebx-6+4]
879
        mov     [ebx+4], ax
880
        sub     ebx, 6
881
        mov     [ebp+.FoundState], ebx
882
        cmp     byte [ebx+1], .MAX_FREQ
883
        jbe     @f
884
        call    .rescale
885
@@:
886
        jmp     .dscmn
887
; CDecodeInfo::DecodeSymbol1 end
888
.binsymbol:
889
; CDecodeInfo::DecodeBinSymbol start
890
        lea     ebx, [esi+2]
891
        mov     ecx, [esi+8]
892
        movzx   ecx, word [ecx]
893
        call    .GetBinSumm
894
        movzx   eax, word [ecx]
895
        call    .RangeDecoder.DecodeBit
896
        jc      .ds3
897
        mov     [ebp+.FoundState], ebx
898
        cmp     byte [ebx+1], 128
899
        adc     byte [ebx+1], 0
900
        movzx   eax, word [ecx]
901
        add     eax, 1 shl (.PERIOD_BITS-2)
902
        shr     eax, .PERIOD_BITS
903
        sub     eax, .INTERVAL
904
        sub     [ecx], ax
905
        mov     [ebp+.PrevSuccess], 1
906
        add     [ebp+.RunLength], 1
907
        jmp     .dscmn
908
.ds3:
909
        movzx   eax, word [ecx]
910
        add     eax, 1 shl (.PERIOD_BITS-2)
911
        shr     eax, .PERIOD_BITS
912
        sub     [ecx], ax
913
        movzx   eax, word [ecx]
914
        shr     eax, 10
915
        movzx   eax, [.ExpEscape+eax]
916
        mov     [ebp+.InitEsc], eax
917
        mov     [ebp+.NumMasked], 1
918
        mov     al, [ebp+.EscCount]
919
        movzx   edx, byte [ebx]
920
        mov     [ebp+.CharMask+edx], al
921
        mov     [ebp+.PrevSuccess], 0
922
        and     [ebp+.FoundState], 0
923
; CDecodeInfo::DecodeBinSymbol end
924
.dscmn:
925
        cmp     [ebp+.FoundState], 0
926
        jnz     .dsfnd
927
.ds4:
928
        add     [ebp+.OrderFall], 1
929
        mov     eax, [ebp+.MinContext]
930
        mov     eax, [eax+8]
931
        test    eax, eax
932
        jz      return.err      ; no end-of-stream mark
933
        mov     [ebp+.MinContext], eax
934
        movzx   ecx, word [eax]
935
        sub     ecx, [ebp+.NumMasked]
936
        jz      .ds4
937
; CDecodeInfo::DecodeSymbol2 start
938
        call    .makeEscFreq2
939
        push    eax
940
        mov     ebx, [esi+4]
941
        sub     ebx, 6
942
        sub     esp, 256*4
943
        mov     esi, esp
944
        xor     eax, eax
945
        push    eax
946
@@:
947
        add     ebx, 6
948
        mov     al, [ebx]
949
        mov     al, [ebp+.CharMask+eax]
950
        cmp     al, [ebp+.EscCount]
951
        jz      @b
952
        mov     al, [ebx+1]
953
        add     [esp], eax
954
        mov     [esi], ebx
955
        add     esi, 4
956
        sub     ecx, 1
957
        jnz     @b
958
        add     edx, [esp]
959
        mov     ecx, edx
960
        mov     eax, [ebp+.range]
961
        xor     edx, edx
962
        div     ecx
963
        mov     [ebp+.range], eax
964
        mov     eax, [ebp+.code]
965
        xor     edx, edx
966
        div     [ebp+.range]
967
        cmp     eax, [esp]
968
        jae     .ds5
969
        pop     ecx
970
        mov     esi, esp
971
        xor     ecx, ecx
972
@@:
973
        mov     ebx, [esi]
974
        add     esi, 4
975
        movzx   edx, byte [ebx+1]
976
        add     ecx, edx
977
        cmp     eax, ecx
978
        jae     @b
979
        mov     eax, ecx
980
        movzx   edx, byte [ebx+1]
981
        sub     eax, edx
982
        call    .RangeDecoder.Decode
983
        add     esp, 256*4
984
        pop     eax
985
        mov     cl, [eax+2]
986
        cmp     cl, .PERIOD_BITS
987
        jae     @f
988
        sub     byte [eax+3], 1
989
        jnz     @f
990
        shl     word [eax], 1
991
        mov     dl, 3
992
        shl     dl, cl
993
        mov     [eax+3], dl
994
        add     byte [eax+2], 1
995
@@:
996
.update2:
997
        mov     [ebp+.FoundState], ebx
998
        add     byte [ebx+1], 4
999
        mov     esi, [ebp+.MinContext]
1000
        add     word [esi+2], 4
1001
        cmp     byte [ebx+1], .MAX_FREQ
1002
        jbe     @f
1003
        call    .rescale
1004
@@:
1005
        add     [ebp+.EscCount], 1
1006
        mov     eax, [ebp+.InitRL]
1007
        mov     [ebp+.RunLength], eax
1008
        jmp     .dsfnd
1009
.ds5:
1010
        pop     eax
1011
        mov     edx, ecx
1012
        sub     edx, eax
1013
        call    .RangeDecoder.Decode
1014
        mov     eax, [ebp+.MinContext]
1015
        movzx   eax, word [eax]
1016
        mov     ebx, eax
1017
        sub     ebx, [ebp+.NumMasked]
1018
        mov     [ebp+.NumMasked], eax
1019
        mov     esi, esp
1020
        mov     al, [ebp+.EscCount]
1021
@@:
1022
        mov     edx, [esi]
1023
        add     esi, 4
1024
        movzx   edx, byte [edx]
1025
        mov     [ebp+.CharMask+edx], al
1026
        sub     ebx, 1
1027
        jnz     @b
1028
        add     esp, 256*4
1029
        pop     eax
1030
        add     word [eax], cx
1031
; CDecodeInfo::DecodeSymbol2 end
1032
        cmp     [ebp+.FoundState], 0
1033
        jz      .ds4
1034
.dsfnd:
1035
        mov     eax, [ebp+.FoundState]
1036
        mov     al, [eax]
1037
        stosb
1038
 
1039
.NextContext:
1040
; CInfo::NextContext(void)
1041
        mov     ebx, [ebp+.FoundState]
1042
        mov     ebx, [ebx+2]
1043
        cmp     [ebp+.OrderFall], 0
1044
        jnz     .nc0
1045
        cmp     ebx, [ebp+.pText]
1046
        jbe     .nc0
1047
        mov     [ebp+.MinContext], ebx
1048
        mov     [ebp+.MaxContext], ebx
1049
        ret
1050
.nc0:
1051
        call    .UpdateModel
1052
        cmp     [ebp+.EscCount], 0
1053
        jz      @f
1054
        ret
1055
@@:
1056
        mov     [ebp+.EscCount], 1
1057
        push    edi
1058
        lea     edi, [ebp+.CharMask]
1059
        mov     ecx, 256/4
1060
        xor     eax, eax
1061
        rep     stosd
1062
        pop     edi
1063
        ret
1064
 
1065
.makeEscFreq2:
1066
; CInfo::makeEscFreq2(ecx=Diff)->{eax->SEE2_CONTEXT,edx=scale}
1067
        mov     esi, [ebp+.MinContext]
1068
        cmp     word [esi], 256
1069
        jz      .mef0
1070
        movzx   edx, [.NS2Indx+ecx-1]
1071
        shl     edx, 4
1072
        mov     eax, [esi+8]
1073
        movzx   eax, word [eax]
1074
        sub     ax, [esi]
1075
        cmp     ecx, eax
1076
        adc     edx, 0
1077
        movzx   eax, word [esi]
1078
        push    edx
1079
        lea     edx, [eax*9]
1080
        lea     edx, [edx+eax*2]
1081
        movzx   eax, word [esi+2]
1082
        cmp     eax, edx
1083
        pop     edx
1084
        setc    al
1085
        movzx   eax, al
1086
        lea     edx, [edx+eax*2]
1087
        cmp     ecx, [ebp+.NumMasked]
1088
        setc    al
1089
        lea     edx, [edx+eax*4]
1090
        add     dl, [ebp+.HiBitsFlag]
1091
        lea     eax, [ebp+edx*4+.SEE2Cont]
1092
        movzx   edx, word [eax]
1093
        push    ecx
1094
        mov     cl, [eax+2]
1095
        shr     edx, cl
1096
        sub     [eax], dx
1097
        pop     ecx
1098
        cmp     edx, 1
1099
        adc     edx, 0
1100
        ret
1101
.mef0:
1102
        lea     eax, [ebp+.DummySEE2Cont]
1103
        mov     edx, 1
1104
        ret
1105
 
1106
.RangeDecoder.DecodeBit:
1107
; CRangeDecoder::DecodeBit(eax=size0,numTotalBits=.TOT_BITS)
1108
        mov     edx, [ebp+.range]
1109
        shr     edx, .TOT_BITS
1110
        imul    eax, edx
1111
        cmp     [ebp+.code], eax
1112
        jae     .rddb
1113
        mov     [ebp+.range], eax
1114
        call    .RangeDecoder.Normalize
1115
        clc
1116
        ret
1117
.rddb:
1118
        sub     [ebp+.code], eax
1119
        sub     [ebp+.range], eax
1120
        call    .RangeDecoder.Normalize
1121
        stc
1122
        ret
1123
 
1124
.RangeDecoder.Decode:
1125
        imul    eax, [ebp+.range]
1126
        sub     [ebp+.code], eax
1127
        mov     eax, [ebp+.range]
1128
        imul    eax, edx
1129
        mov     [ebp+.range], eax
1130
.RangeDecoder.Normalize:
1131
        cmp     byte [ebp+.range+3], 0
1132
        jz      @f
1133
        ret
1134
@@:
1135
        sub     [ebp+.inLen], 1
1136
        js      .refill
1137
.filled:
1138
        shl     [ebp+.range], 8
1139
        shl     [ebp+.code], 8
1140
        mov     eax, [ebp+.inPtr]
1141
        add     [ebp+.inPtr], 1
1142
        mov     al, [eax]
1143
        mov     byte [ebp+.code], al
1144
        jmp     .RangeDecoder.Normalize
1145
.refill:
1146
        mov     eax, [ebp+.inStream]
1147
        call    fillBuf
1148
        push    [eax+streamInfo.bufPtr]
1149
        pop     [ebp+.inPtr]
1150
        mov     eax, [eax+streamInfo.bufDataLen]
1151
        sub     eax, 1
1152
        js      return.err
1153
        mov     [ebp+.inLen], eax
1154
        jmp     .filled
1155
 
1156
.GlueFreeBlocks:
1157
; CSubAllocator::GlueFreeBlocks, called from AllocUnitsRare
1158
        push    eax
1159
        mov     [ebp+.GlueCount], 255
1160
        mov     edx, [ebp+.HeapStart]
1161
        add     edx, [ebp+.usedMemorySize]
1162
        ; we need add extra MEM_BLK with Stamp=0
1163
        and     word [edx], 0
1164
        add     edx, .UNIT_SIZE
1165
        mov     eax, [ebp+.LoUnit]
1166
        cmp     eax, [ebp+.HiUnit]
1167
        jz      @f
1168
        mov     byte [eax], 0
1169
@@:
1170
        mov     [edx+4], edx
1171
        mov     [edx+8], edx
1172
        push    ecx
1173
        xor     ecx, ecx
1174
.gfb1:
1175
        mov     eax, [ebp+ecx*4+.FreeList]
1176
        test    eax, eax
1177
        jz      .gfb2
1178
        push    dword [eax]
1179
        pop     dword [ebp+ecx*4+.FreeList]
1180
        mov     [eax+8], edx
1181
        push    edx
1182
        mov     edx, [edx+4]
1183
        mov     [eax+4], edx
1184
        mov     [edx+8], eax
1185
        or      word [eax], 0xFFFF
1186
        movzx   edx, [.Indx2Units+ecx]
1187
        mov     [eax+2], dx
1188
        pop     edx
1189
        mov     [edx+4], eax
1190
        jmp     .gfb1
1191
.gfb2:
1192
        inc     ecx
1193
        cmp     ecx, .N_INDEXES
1194
        jb      .gfb1
1195
        mov     ecx, edx
1196
.gfb3:
1197
        mov     ecx, [ecx+4]
1198
        cmp     ecx, edx
1199
        jz      .gfb5
1200
.gfb4:
1201
        movzx   eax, word [ecx+2]
1202
        lea     eax, [eax*3]
1203
        lea     eax, [ecx+eax*4]
1204
        cmp     word [eax], 0xFFFF
1205
        jnz     .gfb3
1206
        push    eax
1207
        mov     ax, [eax+2]
1208
        add     ax, [ecx+2]
1209
        pop     eax
1210
        jc      .gfb3
1211
        push    edx
1212
        mov     edx, [eax+4]
1213
        push    dword [eax+8]
1214
        pop     dword [edx+8]
1215
        mov     edx, [eax+8]
1216
        push    dword [eax+4]
1217
        pop     dword [edx+4]
1218
        pop     edx
1219
        mov     ax, [eax+2]
1220
        add     [ecx+2], ax
1221
        jmp     .gfb4
1222
.gfb5:
1223
        mov     ecx, [edx+4]
1224
        cmp     ecx, edx
1225
        jz      .gfb8
1226
        mov     eax, [ecx+4]
1227
        mov     [eax+8], edx
1228
        mov     [edx+4], eax
1229
        movzx   eax, word [ecx+2]
1230
        push    edx
1231
.gfb6:
1232
        sub     eax, 128
1233
        jbe     .gfb7
1234
        mov     edx, ecx
1235
        xchg    edx, [ebp+.FreeList+(.N_INDEXES-1)*4]
1236
        mov     [ecx], edx
1237
        add     ecx, 128*.UNIT_SIZE
1238
        jmp     .gfb6
1239
.gfb7:
1240
        add     eax, 128
1241
        movzx   edx, [.Units2Indx+eax-1]
1242
        cmp     [.Indx2Units+edx], al
1243
        jz      @f
1244
        dec     edx
1245
        push    edx
1246
        movzx   edx, [.Indx2Units+edx]
1247
        sub     eax, edx
1248
        lea     eax, [ebp+.FreeList+(eax-1)*4]
1249
        lea     edx, [edx*3]
1250
        lea     edx, [ecx+edx*4]
1251
        push    dword [eax]
1252
        pop     dword [edx]
1253
        mov     [eax], edx
1254
        pop     edx
1255
@@:
1256
        mov     eax, ecx
1257
        xchg    eax, [ebp+.FreeList+edx*4]
1258
        mov     [ecx], eax
1259
        pop     edx
1260
        jmp     .gfb5
1261
.gfb8:
1262
        pop     ecx
1263
        pop     eax
1264
        mov     edx, [ebp+.FreeList+eax*4]
1265
        test    edx, edx
1266
        jz      .aur.cont
1267
        push    edx
1268
        mov     edx, [edx]
1269
        mov     [ebp+.FreeList+eax*4], edx
1270
        pop     eax
1271
        ret
1272
 
1273
.AllocContext:
1274
; CSubAllocator::AllocContext
1275
        mov     eax, [ebp+.HiUnit]
1276
        cmp     eax, [ebp+.LoUnit]
1277
        jz      @f
1278
        sub     eax, .UNIT_SIZE
1279
        mov     [ebp+.HiUnit], eax
1280
        ret
1281
@@:
1282
        mov     eax, [ebp+.FreeList]
1283
        test    eax, eax
1284
        jz      @f
1285
        mov     edx, [eax]
1286
        mov     [ebp+.FreeList], edx
1287
        ret
1288
@@:
1289
        xor     eax, eax
1290
        jmp     .AllocUnitsRare
1291
 
1292
.AllocUnits:
1293
; CSubAllocator::AllocUnits(ecx)
1294
        movzx   ecx, [.Units2Indx+ecx-1]
1295
        mov     eax, [ebp+.FreeList+ecx*4]
1296
        test    eax, eax
1297
        jz      @f
1298
        mov     edx, [eax]
1299
        mov     [ebp+.FreeList+ecx*4], edx
1300
        ret
1301
@@:
1302
        mov     eax, [ebp+.LoUnit]
1303
        movzx   edx, [.Indx2Units+ecx]
1304
        lea     edx, [edx*3]
1305
        lea     eax, [eax+edx*4]
1306
        cmp     eax, [ebp+.HiUnit]
1307
        ja      @f
1308
        xchg    eax, [ebp+.LoUnit]
1309
        ret
1310
@@:
1311
        mov     eax, ecx
1312
 
1313
.AllocUnitsRare:
1314
; CSubAllocator::AllocUnitsRare(eax)
1315
        cmp     [ebp+.GlueCount], 0
1316
        jz      .GlueFreeBlocks
1317
.aur.cont:
1318
        push    eax
1319
.aur1:
1320
        inc     eax
1321
        cmp     eax, .N_INDEXES
1322
        jz      .aur3
1323
        mov     edx, [ebp+.FreeList+eax*4]
1324
        test    edx, edx
1325
        jz      .aur1
1326
        push    edx
1327
        mov     edx, [edx]
1328
        mov     [ebp+.FreeList+eax*4], edx
1329
        call    .SplitBlock
1330
        pop     eax
1331
        pop     edx
1332
        ret
1333
.aur3:
1334
        dec     [ebp+.GlueCount]
1335
        pop     eax
1336
        movzx   eax, [.Indx2Units+eax]
1337
        lea     edx, [eax*3]
1338
        shl     edx, 2
1339
        mov     eax, [ebp+.UnitsStart]
1340
        sub     eax, [ebp+.pText]
1341
        cmp     eax, edx
1342
        jbe     .aur4
1343
        mov     eax, [ebp+.UnitsStart]
1344
        sub     eax, edx
1345
        mov     [ebp+.UnitsStart], eax
1346
        ret
1347
.aur4:
1348
        xor     eax, eax
1349
        ret
1350
 
1351
.SplitBlock:
1352
; CSubAllocator::SplitBlock(pv=[esp+4],oldIndx=eax,newIndx=[esp+8])
1353
        push    eax
1354
        mov     edx, [esp+12]
1355
        movzx   eax, [.Indx2Units+eax]
1356
        movzx   edx, [.Indx2Units+edx]
1357
        sub     eax, edx
1358
        lea     edx, [edx*3]
1359
        push    ecx
1360
        mov     ecx, [esp+12]
1361
        lea     ecx, [ecx+edx*4]
1362
        movzx   edx, [.Units2Indx+eax-1]
1363
        cmp     [.Indx2Units+edx], al
1364
        jz      .aur2
1365
        push    dword [ebp+.FreeList+(edx-1)*4]
1366
        pop     dword [ecx]
1367
        mov     [ebp+.FreeList+(edx-1)*4], ecx
1368
        movzx   edx, [.Indx2Units+edx-1]
1369
        sub     eax, edx
1370
        lea     edx, [edx*3]
1371
        lea     ecx, [ecx+edx*4]
1372
.aur2:
1373
        movzx   eax, [.Units2Indx+eax-1]
1374
        push    dword [ebp+.FreeList+eax*4]
1375
        pop     dword [ecx]
1376
        mov     [ebp+.FreeList+eax*4], ecx
1377
        pop     ecx
1378
        pop     eax
1379
        ret
1380
 
1381
.ExpandUnits:
1382
; CSubAllocator::ExpandUnits(void* oldPtr=esi, int oldNU=eax)
1383
        push    edx
1384
        movzx   edx, [.Units2Indx + eax - 1]
1385
        cmp     dl, [.Units2Indx + eax]
1386
        jnz     @f
1387
        pop     edx
1388
        mov     eax, esi
1389
        ret
1390
@@:
1391
        push    eax ecx edx
1392
        lea     ecx, [eax+1]
1393
        call    .AllocUnits
1394
        pop     edx
1395
        test    eax, eax
1396
        jz      @f
1397
        push    esi edi
1398
        mov     edi, eax
1399
        mov     ecx, [esp+8+4]
1400
        lea     ecx, [ecx*3]
1401
        rep     movsd
1402
        pop     edi esi
1403
        mov     ecx, [ebp+.FreeList+edx*4]
1404
        mov     [esi], ecx
1405
        mov     [ebp+.FreeList+edx*4], esi
1406
@@:
1407
        pop     ecx
1408
        add     esp, 4
1409
        pop     edx
1410
        ret
1411
 
1412
.ShrinkUnits:
1413
; CSubAllocator::ShrinkUnits(void* oldPtr=eax, int oldNU=ebx, int newNU=ecx)
1414
        push    ecx
1415
        movzx   ebx, [.Units2Indx+ebx-1]
1416
        movzx   ecx, [.Units2Indx+ecx-1]
1417
        cmp     ebx, ecx
1418
        jnz     @f
1419
        pop     ecx
1420
        ret
1421
@@:
1422
        mov     edx, [ebp+.FreeList+ecx*4]
1423
        test    edx, edx
1424
        jz      @f
1425
        push    dword [edx]
1426
        pop     [ebp+.FreeList+ecx*4]
1427
        pop     ecx
1428
        push    esi edi
1429
        mov     esi, eax
1430
        mov     edi, edx
1431
        lea     ecx, [ecx*3]
1432
        rep     movsd
1433
        pop     edi esi
1434
        mov     ecx, [ebp+.FreeList+ebx*4]
1435
        mov     [eax], ecx
1436
        mov     [ebp+.FreeList+ebx*4], eax
1437
        mov     eax, edx
1438
        ret
1439
@@:
1440
        push    ecx
1441
        push    eax
1442
        mov     eax, ebx
1443
        call    .SplitBlock
1444
        pop     eax
1445
        pop     ecx
1446
        pop     ecx
1447
        ret
1448
 
1449
.FreeUnits:
1450
; CSubAllocator::FreeUnits(void* ptr=eax, int oldNU=ebx)
1451
        movzx   ebx, [.Units2Indx+ebx-1]
1452
        push    [ebp+.FreeList+ebx*4]
1453
        pop     dword [eax]
1454
        mov     [ebp+.FreeList+ebx*4], eax
1455
        ret
1456
 
1457
ppmd_get_buf_size:
1458
        cmp     dword [esi-4], 5
1459
        jb      return.err
1460
        lodsb
1461
        lodsd
1462
        cmp     eax, ppmd_decoder.kMaxMemBlockSize
1463
        ja      return.err
1464
        add     eax, ppmd_decoder.basesize + ppmd_decoder.kExtraSize
1465
        mov     edx, 0x4000
1466
        ret
1467
 
1468
ppmd_init_decoder:
1469
        mov     [ebp+ppmd_decoder.bInited], 0
1470
; CDecoder::SetDecoderProperties2
1471
        lodsb
1472
        mov     [ebp+ppmd_decoder.order], al
1473
        lodsd
1474
        mov     [ebp+ppmd_decoder.usedMemorySize], eax
1475
; CSubAllocator::CSubAllocator
1476
        xor     eax, eax
1477
        mov     [ebp+ppmd_decoder.GlueCount], al
1478
        lea     edi, [ebp+ppmd_decoder.LoUnit]
1479
        mov     ecx, (ppmd_decoder.SEE2Cont - ppmd_decoder.LoUnit)/4
1480
        rep     stosd
1481
; CSubAllocator::StartSubAllocator
1482
        lea     eax, [ebp+ppmd_decoder.Base+ppmd_decoder.UNIT_SIZE]
1483
        mov     [ebp+ppmd_decoder.HeapStart], eax
1484
        mov     [ebp+streamInfo.fillBuf], ppmd_decoder.fillBuf
1485
        ret