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