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