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