Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
589 diamond 1
; Branch filters for 7-Zip archives: BCJ and BCJ2.
2
; Ported from C++ sources of 7-Zip (c) Igor Pavlov.
3
virtual at 0
4
bcj_decoder:
5
.outStream      rb      streamInfo.size
6
.inStream       dd      ?
7
.inPtr          dd      ?
8
.inSize         dd      ?
9
.nowPos         dd      ?               ; offset in stream
10
.prevPos        dd      ?               ; pointer in buffer
11
.prevMask       db      ?
12
.numRest        db      ?
13
                rw      1
14
.dwordRest      dd      ?
15
.tempSize       dd      ?
16
.tempDword      dd      ?
17
.size = $
18
end virtual
19
 
20
bcj_get_buf_size:
21
        mov     eax, bcj_decoder.size
22
        mov     edx, 0x4000
23
        ret
24
 
25
bcj_init_decoder:
26
        mov     [ebp+streamInfo.fillBuf], bcj_fillBuf
27
        xor     edx, edx
28
        mov     [ebp+bcj_decoder.inPtr], edx
29
        mov     [ebp+bcj_decoder.inSize], edx
30
        mov     [ebp+bcj_decoder.prevPos], edx
31
        mov     [ebp+bcj_decoder.nowPos], edx
32
        mov     [ebp+bcj_decoder.numRest], dl
33
        ret
34
 
35
bcj_fillBuf:
36
        add     [eax+bcj_decoder.nowPos], ecx
37
        mov     ebp, ecx        ; save output size
38
        mov     esi, [eax+bcj_decoder.inPtr]
39
        mov     ebx, [eax+bcj_decoder.inStream]
40
        mov     ecx, [eax+bcj_decoder.inSize]
41
        add     esi, [ebx+streamInfo.bufPtr]
42
        mov     ebx, eax
43
        cmp     [eax+bcj_decoder.prevPos], 0
44
        jz      @f
45
        add     [eax+bcj_decoder.prevPos], edi
46
@@:
47
        cmp     [ebx+bcj_decoder.numRest], 0
48
        jz      .mainloop
49
        sub     ebp, 1
50
        js      .mainloopdone
51
        dec     [ebx+bcj_decoder.numRest]
52
        mov     eax, [ebx+bcj_decoder.dwordRest]
53
        stosb
54
        shr     eax, 8
55
        mov     [ebx+bcj_decoder.dwordRest], eax
56
        jmp     @b
57
.mainloop:
58
        sub     ebp, 1
59
        js      .mainloopdone
60
        sub     ecx, 1
61
        js      .refill1
62
.filled1:
63
        lodsb
64
.filled2:
65
        stosb
66
        cmp     al, 0xE8
67
        jz      .filter
68
        cmp     al, 0xE9
69
        jnz     .mainloop
70
.filter:
71
        and     [ebx+bcj_decoder.tempSize], 0
72
        sub     ecx, 4
73
        jb      .nopos
74
        js      .nopos2
75
        lodsd
76
        push    eax
77
.posok:
78
        xor     edx, edx
79
        mov     eax, edi
80
        sub     eax, [ebx+bcj_decoder.prevPos]
81
        cmp     eax, 5
82
        ja      .maskok
83
        movzx   edx, [ebx+bcj_decoder.prevMask]
84
@@:
85
        and     edx, 0x77
86
        add     edx, edx
87
        sub     eax, 1
88
        jnz     @b
89
.maskok:
90
        mov     [ebx+bcj_decoder.prevMask], dl
91
        mov     [ebx+bcj_decoder.prevPos], edi
92
        mov     al, [esp+3]
93
        add     al, 1
94
        cmp     al, 2
95
        jae     .miss
96
        cmp     dl, 0x20
97
        jae     .miss2
98
        lea     eax, [edx-1]
99
        test    eax, edx
100
        jnz     .miss2
101
        pop     eax
102
        shr     edx, 1
103
        push    ecx
104
        mov     cl, [bcj_kMaskToBitNumber+edx]
105
iglobal
106
bcj_kMaskToBitNumber db 24,16,8,8,0,0,0,0
107
endg
108
@@:
109
        sub     eax, [ebx+bcj_decoder.nowPos]
110
        add     eax, [ebx+streamInfo.bufDataLen]
111
        sub     eax, edi
112
        sub     eax, 4
113
        add     eax, [ebx+streamInfo.bufPtr]
114
        cmp     cl, 24
115
        jz      @f
116
        push    eax
117
        shr     eax, cl
118
        add     al, 1
119
        cmp     al, 2
120
        pop     eax
121
        jae     @f
122
        mov     edx, 0x100
123
        shl     edx, cl
124
        sub     edx, 1
125
        xor     eax, edx
126
        jmp     @b
127
@@:
128
        pop     ecx
129
        shl     eax, 7
130
        sar     eax, 7
131
        sub     ebp, 4
132
        jb      .finalize_dword
133
        stosd
134
        jmp     .mainloop
135
.miss2:
136
        or      [ebx+bcj_decoder.prevMask], 10h
137
.miss:
138
        or      [ebx+bcj_decoder.prevMask], 1
139
        cmp     [ebx+bcj_decoder.tempSize], 0
140
        jz      @f
141
        lea     esi, [ebx+bcj_decoder.tempDword]
142
        pop     dword [esi]
143
        mov     ecx, [ebx+bcj_decoder.tempSize]
144
        jmp     .mainloop
145
@@:
146
        pop     eax
147
        sub     esi, 4
148
        add     ecx, 4
149
        jmp     .mainloop
150
.finalize_dword:
151
        add     ebp, 4
152
        mov     [ebx+bcj_decoder.numRest], 4
153
@@:
154
        dec     ebp
155
        js      .save_dword
156
        stosb
157
        dec     [ebx+bcj_decoder.numRest]
158
        shr     eax, 8
159
        jmp     @b
160
.save_dword:
161
        mov     [ebx+bcj_decoder.dwordRest], eax
162
.mainloopdone:
163
        mov     eax, [ebx+bcj_decoder.prevPos]
164
        test    eax, eax
165
        jz      .noprev
166
        sub     eax, edi
167
        mov     [ebx+bcj_decoder.prevPos], eax
168
.noprev:
169
        mov     eax, [ebx+bcj_decoder.inStream]
170
        sub     esi, [eax+streamInfo.bufPtr]
171
        mov     [ebx+bcj_decoder.inPtr], esi
172
        mov     [ebx+bcj_decoder.inSize], ecx
173
        popad
174
        ret
175
 
176
.refill1:
177
        cmp     ecx, -1
178
        jz      .refill0
179
        lodsb
180
        cmp     ecx, -4
181
        jnz     @f
182
        mov     ecx, [ebx+bcj_decoder.inStream]
183
        mov     esi, [ecx+streamInfo.bufPtr]
184
        mov     ecx, [ecx+streamInfo.bufDataLen]
185
@@:
186
        jmp     .filled2
187
.refill0:
188
        mov     eax, [ebx+bcj_decoder.inStream]
189
        call    fillBuf
190
        mov     esi, [eax+streamInfo.bufPtr]
191
        mov     ecx, [eax+streamInfo.bufDataLen]
192
        sub     ecx, 1
193
        js      return.err
194
        jmp     .filled1
195
 
196
.nopos:
197
        mov     eax, [ebx+bcj_decoder.inStream]
198
        cmp     dword [eax+streamInfo.fullSize+4], 0
199
        jnz     .hasdata
200
        push    ecx
201
        add     ecx, dword [eax+streamInfo.fullSize]
202
        pop     ecx
203
        jc      .hasdata
204
        add     ecx, 4
205
        jmp     .mainloop
206
.hasdata:
207
        mov     [ebx+bcj_decoder.tempSize], ecx
208
        push    0
209
        push    edi
210
        lea     edi, [esp+4]
211
        add     ecx, 4
212
        rep     movsb
213
        sub     esi, ebx
214
        sub     esi, 1
215
        cmp     esi, bcj_decoder.tempDword+4
216
        jbe     @f
217
        call    fillBuf
218
@@:
219
        mov     esi, [eax+streamInfo.bufPtr]
220
        mov     ecx, [ebx+bcj_decoder.tempSize]
221
        neg     ecx
222
        rep     movsb
223
        pop     edi
224
        mov     ecx, [eax+streamInfo.bufDataLen]
225
        add     ecx, [ebx+bcj_decoder.tempSize]
226
        cmp     [ebx+bcj_decoder.tempSize], -4
227
        jnz     .posok
228
        and     [ebx+bcj_decoder.tempSize], 0
229
        jmp     .posok
230
.nopos2:
231
        mov     eax, [ebx+bcj_decoder.inStream]
232
        add     ecx, 4
233
        jmp     .hasdata
234
 
235
virtual at 0
236
bcj2_decoder:
237
.outStream      rb      streamInfo.size
238
.mainInStream   dd      ?
239
.callStream     dd      ?
240
.jumpStream     dd      ?
241
.rangeDecoder   dd      ?
242
.dwordRest      dd      ?
243
.prevByte       db      ?
244
.numRest        db      ?
245
.bInited        db      ?
246
                rb      1
247
.inPtr          dd      ?
248
.inSize         dd      ?
249
.callPtr        dd      ?
250
.jumpPtr        dd      ?
251
.callSize       dd      ?
252
.jumpSize       dd      ?
253
.rangeDecPtr    dd      ?
254
.rangeDecSize   dd      ?
255
.nowPos         dd      ?
256
.range          dd      ?
257
.code           dd      ?
258
.statusE9Decoder dd     ?
259
.statusJccDecoder dd    ?
260
.statusE8Decoder rd     256
261
.size = $
262
end virtual
263
 
264
bcj2_get_buf_size:
265
        mov     eax, bcj2_decoder.size
266
        mov     edx, 0x4000
267
        ret
268
 
269
bcj2_init_decoder:
270
        mov     [ebp+streamInfo.fillBuf], bcj2_fillBuf
271
	mov	eax, lzma_decoder.kBitModelTotal/2
272
        mov     ecx, 256+1+1
273
	lea	edi, [ebp+bcj2_decoder.statusE9Decoder]
274
	rep	stosd
275
        mov     dword [ebp+bcj2_decoder.prevByte], ecx
276
        mov     [ebp+bcj2_decoder.inSize], ecx
277
        mov     [ebp+bcj2_decoder.callSize], ecx
278
        mov     [ebp+bcj2_decoder.jumpSize], ecx
279
        mov     [ebp+bcj2_decoder.rangeDecSize], ecx
280
        mov     [ebp+bcj2_decoder.nowPos], ecx
281
        ret
282
 
283
bcj2_fillBuf.init:
284
        mov     eax, [eax+bcj2_decoder.rangeDecoder]
285
        call    fillBuf
286
        mov     edx, [eax+streamInfo.bufDataLen]
287
        sub     edx, 5
288
        jb      return.err
289
        mov     [ebp+bcj2_decoder.rangeDecSize], edx
290
        mov     edx, [eax+streamInfo.bufPtr]
291
        add     edx, 5
292
        mov     [ebp+bcj2_decoder.rangeDecPtr], edx
293
        mov     edx, [edx-4]
294
        bswap   edx
295
        mov     [ebp+bcj2_decoder.code], edx
296
        or      [ebp+bcj2_decoder.range], -1
297
        mov     [ebp+bcj2_decoder.bInited], 1
298
        mov     eax, ebp
299
        jmp     bcj2_fillBuf.inited
300
 
301
bcj2_fillBuf:
302
        mov     ebp, eax
303
        cmp     [eax+bcj2_decoder.bInited], 0
304
        jz      .init
305
.inited:
306
        add     [eax+bcj2_decoder.nowPos], ecx
307
        mov     esi, [eax+bcj2_decoder.inPtr]
308
@@:
309
        cmp     [ebp+bcj2_decoder.numRest], 0
310
        jz      .mainloop
311
        sub     ecx, 1
312
        js      .mainloopdone
313
        dec     [ebp+bcj2_decoder.numRest]
314
        mov     eax, [ebp+bcj2_decoder.dwordRest]
315
        stosb
316
        mov     [ebp+bcj2_decoder.prevByte], al
317
        shr     eax, 8
318
        mov     [ebp+bcj2_decoder.dwordRest], eax
319
        jmp     @b
320
.mainloop:
321
        sub     ecx, 1
322
        js      .mainloopdone
323
        sub     [ebp+bcj2_decoder.inSize], 1
324
        js      .refill1
325
.filled1:
326
        lodsb
327
        stosb
328
        cmp     al, 0xE8
329
        jz      .e8
330
        cmp     al, 0xE9
331
        jz      .e9
332
        cmp     [ebp+bcj2_decoder.prevByte], 0xF
333
        mov     [ebp+bcj2_decoder.prevByte], al
334
        jnz     .mainloop
335
        and     al, 0xF0
336
        cmp     al, 0x80
337
        jnz     .mainloop
338
.jcc:
339
        lea     eax, [ebp+bcj2_decoder.statusJccDecoder]
340
        call    .RangeDecoderBitDecode
341
        jnc     .mainloop
342
        jmp     .getptrj
343
.e8:
344
        movzx   eax, al
345
        xchg    al, [ebp+bcj2_decoder.prevByte]
346
        lea     eax, [ebp+bcj2_decoder.statusE8Decoder+eax*4]
347
        call    .RangeDecoderBitDecode
348
        jnc     .mainloop
349
        lea     eax, [ebp+bcj2_decoder.callPtr]
350
        jmp     .getptr
351
.e9:
352
        mov     [ebp+bcj2_decoder.prevByte], al
353
        lea     eax, [ebp+bcj2_decoder.statusE9Decoder]
354
        call    .RangeDecoderBitDecode
355
        jnc     .mainloop
356
.getptrj:
357
        lea     eax, [ebp+bcj2_decoder.jumpPtr]
358
.getptr:
359
        sub     dword [eax+8], 4
360
        js      .refill2
361
.filled2:
362
        add     dword [eax], 4
363
        mov     eax, [eax]
364
        mov     eax, [eax-4]
365
        bswap   eax
366
        sub     eax, [ebp+bcj2_decoder.nowPos]
367
        add     eax, [ebp+streamInfo.bufDataLen]
368
        sub     eax, edi
369
        sub     eax, 4
370
        add     eax, [ebp+streamInfo.bufPtr]
371
        sub     ecx, 4
372
        jb      .finalize_dword
373
        stosd
374
        shr     eax, 24
375
        mov     [ebp+bcj2_decoder.prevByte], al
376
        jmp     .mainloop
377
.finalize_dword:
378
        add     ecx, 4
379
        mov     [ebp+bcj2_decoder.numRest], 4
380
@@:
381
        dec     ecx
382
        js      .save_dword
383
        stosb
384
        dec     [ebp+bcj2_decoder.numRest]
385
        shr     eax, 8
386
        jmp     @b
387
.save_dword:
388
        mov     [ebp+bcj2_decoder.dwordRest], eax
389
.mainloopdone:
390
        mov     [ebp+bcj2_decoder.inPtr], esi
391
        popad
392
        ret
393
 
394
.refill1:
395
        mov     eax, [ebp+bcj2_decoder.mainInStream]
396
        call    fillBuf
397
        mov     edx, [eax+streamInfo.bufDataLen]
398
        dec     edx
399
        js      return.err
400
        mov     [ebp+bcj2_decoder.inSize], edx
401
        mov     esi, [eax+streamInfo.bufPtr]
402
        jmp     .filled1
403
 
404
.refill2:
405
        push    eax
406
        mov     eax, [eax-bcj2_decoder.callPtr+bcj2_decoder.callStream]
407
        call    fillBuf
408
        mov     edx, [eax+streamInfo.bufDataLen]
409
        sub     edx, 4
410
        js      return.err
411
        push    [eax+streamInfo.bufPtr]
412
        mov     eax, [esp+4]
413
        pop     dword [eax]
414
        pop     eax
415
        mov     [eax+8], edx
416
        jmp     .filled2
417
 
418
.refill3:
419
        push    eax
420
        mov     eax, [ebp+bcj2_decoder.rangeDecoder]
421
        call    fillBuf
422
        mov     edx, [eax+streamInfo.bufDataLen]
423
        dec     edx
424
        js      return.err
425
        mov     [ebp+bcj2_decoder.rangeDecSize], edx
426
        mov     edx, [eax+streamInfo.bufPtr]
427
        mov     [ebp+bcj2_decoder.rangeDecPtr], edx
428
        pop     eax
429
        jmp     .filled3
430
 
431
.RangeDecoderBitDecode:
432
; in: eax->prob
433
; out: CF=bit; destroys eax,edx
434
	mov	edx, [ebp+bcj2_decoder.range]
435
	shr	edx, lzma_decoder.kNumBitModelTotalBits
436
	imul	edx, [eax]
437
	cmp	[ebp+bcj2_decoder.code], edx
438
	jae	.ae
439
	mov	[ebp+bcj2_decoder.range], edx
440
	mov	edx, lzma_decoder.kBitModelTotal
441
	sub	edx, [eax]
442
	shr	edx, lzma_decoder.kNumMoveBits
443
	add	[eax], edx
444
	clc
445
.n:
446
	lahf
447
	cmp	[ebp+bcj2_decoder.range], lzma_decoder.kTopValue
448
	jae	@f
449
	shl	[ebp+bcj2_decoder.range], 8
450
	shl	[ebp+bcj2_decoder.code], 8
451
        dec     [ebp+bcj2_decoder.rangeDecSize]
452
        js      .refill3
453
.filled3:
454
        mov     edx, [ebp+bcj2_decoder.rangeDecPtr]
455
        mov     al, [edx]
456
        add     edx, 1
457
        mov     [ebp+bcj2_decoder.rangeDecPtr], edx
458
	mov	byte [ebp+bcj2_decoder.code], al
459
@@:
460
	sahf
461
	ret
462
.ae:
463
	sub	[ebp+bcj2_decoder.range], edx
464
	sub	[ebp+bcj2_decoder.code], edx
465
	mov	edx, [eax]
466
	shr	edx, lzma_decoder.kNumMoveBits
467
	sub	[eax], edx
468
	stc
469
	jmp	.n