Rev 750 | Rev 1635 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 750 | Rev 1450 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2007. 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: 750 $ |
8 | $Revision: 1450 $ |
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 eax |
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 | @@: sub bl, al |
222 | @@: sub bl, al |
223 | jmp .main_loop |
223 | jmp .main_loop |
224 | .1: |
224 | .1: |
225 | lea eax, [.IsRep*4 + ebx*4] |
225 | lea eax, [.IsRep*4 + ebx*4] |
226 | add eax, [.p] |
226 | add eax, [.p] |
227 | call .RangeDecoderBitDecode |
227 | call .RangeDecoderBitDecode |
228 | jnc .10 |
228 | jnc .10 |
229 | lea eax, [.IsRepG0*4 + ebx*4] |
229 | lea eax, [.IsRepG0*4 + ebx*4] |
230 | add eax, [.p] |
230 | add eax, [.p] |
231 | call .RangeDecoderBitDecode |
231 | call .RangeDecoderBitDecode |
232 | jc .111 |
232 | jc .111 |
233 | mov eax, ebx |
233 | mov eax, ebx |
234 | shl eax, .kNumPosBitsMax+2 |
234 | shl eax, .kNumPosBitsMax+2 |
235 | lea eax, [.IsRep0Long*4 + eax + edx*4] |
235 | lea eax, [.IsRep0Long*4 + eax + edx*4] |
236 | add eax, [.p] |
236 | add eax, [.p] |
237 | call .RangeDecoderBitDecode |
237 | call .RangeDecoderBitDecode |
238 | jc .1101 |
238 | jc .1101 |
239 | cmp bl, 7 |
239 | cmp bl, 7 |
240 | setae bl |
240 | setae bl |
241 | lea ebx, [9 + ebx + ebx] |
241 | lea ebx, [9 + ebx + ebx] |
242 | xor edx, edx |
242 | xor edx, edx |
243 | sub edx, [.rep0] |
243 | sub edx, [.rep0] |
244 | mov al, [edi + edx] |
244 | mov al, [edi + edx] |
245 | stosb |
245 | stosb |
246 | mov [.previousByte], al |
246 | mov [.previousByte], al |
247 | jmp .main_loop |
247 | jmp .main_loop |
248 | .111: |
248 | .111: |
249 | lea eax, [.IsRepG1*4 + ebx*4] |
249 | lea eax, [.IsRepG1*4 + ebx*4] |
250 | add eax, [.p] |
250 | add eax, [.p] |
251 | call .RangeDecoderBitDecode |
251 | call .RangeDecoderBitDecode |
252 | mov eax, [.rep1] |
252 | mov eax, [.rep1] |
253 | jnc .l3 |
253 | jnc .l3 |
254 | .l1: |
254 | .l1: |
255 | lea eax, [.IsRepG2*4 + ebx*4] |
255 | lea eax, [.IsRepG2*4 + ebx*4] |
256 | add eax, [.p] |
256 | add eax, [.p] |
257 | call .RangeDecoderBitDecode |
257 | call .RangeDecoderBitDecode |
258 | mov eax, [.rep2] |
258 | mov eax, [.rep2] |
259 | jnc .l2 |
259 | jnc .l2 |
260 | xchg [.rep3], eax |
260 | xchg [.rep3], eax |
261 | .l2: |
261 | .l2: |
262 | push [.rep1] |
262 | push [.rep1] |
263 | pop [.rep2] |
263 | pop [.rep2] |
264 | .l3: |
264 | .l3: |
265 | xchg eax, [.rep0] |
265 | xchg eax, [.rep0] |
266 | mov [.rep1], eax |
266 | mov [.rep1], eax |
267 | .1101: |
267 | .1101: |
268 | mov eax, .RepLencoder*4 |
268 | mov eax, .RepLencoder*4 |
269 | add eax, [.p] |
269 | add eax, [.p] |
270 | call .LzmaLenDecode |
270 | call .LzmaLenDecode |
271 | cmp bl, 7 |
271 | cmp bl, 7 |
272 | setc bl |
272 | setc bl |
273 | adc bl, bl |
273 | adc bl, bl |
274 | xor bl, 3 |
274 | xor bl, 3 |
275 | add bl, 8 |
275 | add bl, 8 |
276 | jmp .repmovsb |
276 | jmp .repmovsb |
277 | .10: |
277 | .10: |
278 | mov eax, [.rep0] |
278 | mov eax, [.rep0] |
279 | xchg eax, [.rep1] |
279 | xchg eax, [.rep1] |
280 | xchg eax, [.rep2] |
280 | xchg eax, [.rep2] |
281 | xchg eax, [.rep3] |
281 | xchg eax, [.rep3] |
282 | cmp bl, 7 |
282 | cmp bl, 7 |
283 | setc bl |
283 | setc bl |
284 | adc bl, bl |
284 | adc bl, bl |
285 | xor bl, 3 |
285 | xor bl, 3 |
286 | add bl, 7 |
286 | add bl, 7 |
287 | mov eax, .Lencoder*4 |
287 | mov eax, .Lencoder*4 |
288 | add eax, [.p] |
288 | add eax, [.p] |
289 | call .LzmaLenDecode |
289 | call .LzmaLenDecode |
290 | mov eax, .kNumLenToPosStates-1 |
290 | mov eax, .kNumLenToPosStates-1 |
291 | cmp eax, ecx |
291 | cmp eax, ecx |
292 | jb @f |
292 | jb @f |
293 | mov eax, ecx |
293 | mov eax, ecx |
294 | @@: |
294 | @@: |
295 | push ecx |
295 | push ecx |
296 | mov ecx, .kNumPosSlotBits |
296 | mov ecx, .kNumPosSlotBits |
297 | shl eax, cl |
297 | shl eax, cl |
298 | shl eax, 2 |
298 | shl eax, 2 |
299 | add eax, .PosSlot*4 |
299 | add eax, .PosSlot*4 |
300 | add eax, [.p] |
300 | add eax, [.p] |
301 | call .RangeDecoderBitTreeDecode |
301 | call .RangeDecoderBitTreeDecode |
302 | mov [.rep0], ecx |
302 | mov [.rep0], ecx |
303 | cmp ecx, .kStartPosModelIndex |
303 | cmp ecx, .kStartPosModelIndex |
304 | jb .l6 |
304 | jb .l6 |
305 | push ecx |
305 | push ecx |
306 | mov eax, ecx |
306 | mov eax, ecx |
307 | and eax, 1 |
307 | and eax, 1 |
308 | shr ecx, 1 |
308 | shr ecx, 1 |
309 | or eax, 2 |
309 | or eax, 2 |
310 | dec ecx |
310 | dec ecx |
311 | shl eax, cl |
311 | shl eax, cl |
312 | mov [.rep0], eax |
312 | mov [.rep0], eax |
313 | pop edx |
313 | pop edx |
314 | cmp edx, .kEndPosModelIndex |
314 | cmp edx, .kEndPosModelIndex |
315 | jae .l5 |
315 | jae .l5 |
316 | sub eax, edx |
316 | sub eax, edx |
317 | shl eax, 2 |
317 | shl eax, 2 |
318 | add eax, (.SpecPos - 1)*4 |
318 | add eax, (.SpecPos - 1)*4 |
319 | add eax, [.p] |
319 | add eax, [.p] |
320 | call .RangeDecoderReverseBitTreeDecode |
320 | call .RangeDecoderReverseBitTreeDecode |
321 | add [.rep0], ecx |
321 | add [.rep0], ecx |
322 | jmp .l6 |
322 | jmp .l6 |
323 | .l5: |
323 | .l5: |
324 | sub ecx, .kNumAlignBits |
324 | sub ecx, .kNumAlignBits |
325 | call .RangeDecoderDecodeDirectBits |
325 | call .RangeDecoderDecodeDirectBits |
326 | mov ecx, .kNumAlignBits |
326 | mov ecx, .kNumAlignBits |
327 | shl eax, cl |
327 | shl eax, cl |
328 | add [.rep0], eax |
328 | add [.rep0], eax |
329 | mov eax, .Align_*4 |
329 | mov eax, .Align_*4 |
330 | add eax, [.p] |
330 | add eax, [.p] |
331 | call .RangeDecoderReverseBitTreeDecode |
331 | call .RangeDecoderReverseBitTreeDecode |
332 | add [.rep0], ecx |
332 | add [.rep0], ecx |
333 | .l6: |
333 | .l6: |
334 | pop ecx |
334 | pop ecx |
335 | inc [.rep0] |
335 | inc [.rep0] |
336 | jz .main_loop_done |
336 | jz .main_loop_done |
337 | .repmovsb: |
337 | .repmovsb: |
338 | add ecx, .kMatchMinLen |
338 | add ecx, .kMatchMinLen |
339 | push esi |
339 | push esi |
340 | mov esi, edi |
340 | mov esi, edi |
341 | sub esi, [.rep0] |
341 | sub esi, [.rep0] |
342 | rep movsb |
342 | rep movsb |
343 | pop esi |
343 | pop esi |
344 | mov al, [edi-1] |
344 | mov al, [edi-1] |
345 | mov [.previousByte], al |
345 | mov [.previousByte], al |
346 | jmp .main_loop |
346 | jmp .main_loop |
347 | .main_loop_done: |
347 | .main_loop_done: |
348 | ret |
348 | ret |
349 | 349 | ||
350 | .RangeDecoderBitDecode: |
350 | .RangeDecoderBitDecode: |
351 | ; in: eax->prob |
351 | ; in: eax->prob |
352 | ; out: CF=bit; destroys eax |
352 | ; out: CF=bit; destroys eax |
353 | push edx |
353 | push edx |
354 | mov edx, [.range] |
354 | mov edx, [.range] |
355 | shr edx, .kNumBitModelTotalBits |
355 | shr edx, .kNumBitModelTotalBits |
356 | imul edx, [eax] |
356 | imul edx, [eax] |
357 | cmp [.code_], edx |
357 | cmp [.code_], edx |
358 | jae .ae |
358 | jae .ae |
359 | mov [.range], edx |
359 | mov [.range], edx |
360 | mov edx, .kBitModelTotal |
360 | mov edx, .kBitModelTotal |
361 | sub edx, [eax] |
361 | sub edx, [eax] |
362 | shr edx, .kNumMoveBits |
362 | shr edx, .kNumMoveBits |
363 | add [eax], edx |
363 | add [eax], edx |
364 | clc |
364 | clc |
365 | .n: |
365 | .n: |
366 | lahf |
366 | lahf |
367 | cmp [.range], .kTopValue |
367 | cmp [.range], .kTopValue |
368 | jae @f |
368 | jae @f |
369 | shl [.range], 8 |
369 | shl [.range], 8 |
370 | shl [.code_], 8 |
370 | shl [.code_], 8 |
371 | lodsb |
371 | lodsb |
372 | mov byte [.code_], al |
372 | mov byte [.code_], al |
373 | @@: |
373 | @@: |
374 | sahf |
374 | sahf |
375 | pop edx |
375 | pop edx |
376 | ret |
376 | ret |
377 | .ae: |
377 | .ae: |
378 | sub [.range], edx |
378 | sub [.range], edx |
379 | sub [.code_], edx |
379 | sub [.code_], edx |
380 | mov edx, [eax] |
380 | mov edx, [eax] |
381 | shr edx, .kNumMoveBits |
381 | shr edx, .kNumMoveBits |
382 | sub [eax], edx |
382 | sub [eax], edx |
383 | stc |
383 | stc |
384 | jmp .n |
384 | jmp .n |
385 | 385 | ||
386 | .RangeDecoderDecodeDirectBits: |
386 | .RangeDecoderDecodeDirectBits: |
387 | ; in: ecx=numTotalBits |
387 | ; in: ecx=numTotalBits |
388 | ; out: eax=result; destroys edx |
388 | ; out: eax=result; destroys edx |
389 | xor eax, eax |
389 | xor eax, eax |
390 | .l: |
390 | .l: |
391 | shr [.range], 1 |
391 | shr [.range], 1 |
392 | shl eax, 1 |
392 | shl eax, 1 |
393 | mov edx, [.code_] |
393 | mov edx, [.code_] |
394 | sub edx, [.range] |
394 | sub edx, [.range] |
395 | jb @f |
395 | jb @f |
396 | mov [.code_], edx |
396 | mov [.code_], edx |
397 | or eax, 1 |
397 | or eax, 1 |
398 | @@: |
398 | @@: |
399 | cmp [.range], .kTopValue |
399 | cmp [.range], .kTopValue |
400 | jae @f |
400 | jae @f |
401 | shl [.range], 8 |
401 | shl [.range], 8 |
402 | shl [.code_], 8 |
402 | shl [.code_], 8 |
403 | push eax |
403 | push eax |
404 | lodsb |
404 | lodsb |
405 | mov byte [.code_], al |
405 | mov byte [.code_], al |
406 | pop eax |
406 | pop eax |
407 | @@: |
407 | @@: |
408 | loop .l |
408 | loop .l |
409 | ret |
409 | ret |
410 | 410 | ||
411 | .LzmaLiteralDecode: |
411 | .LzmaLiteralDecode: |
412 | ; in: eax->probs |
412 | ; in: eax->probs |
413 | ; out: al=byte; destroys edx |
413 | ; out: al=byte; destroys edx |
414 | push ecx |
414 | push ecx |
415 | mov ecx, 1 |
415 | mov ecx, 1 |
416 | @@: |
416 | @@: |
417 | push eax |
417 | push eax |
418 | lea eax, [eax+ecx*4] |
418 | lea eax, [eax+ecx*4] |
419 | call .RangeDecoderBitDecode |
419 | call .RangeDecoderBitDecode |
420 | pop eax |
420 | pop eax |
421 | adc cl, cl |
421 | adc cl, cl |
422 | jnc @b |
422 | jnc @b |
423 | .LzmaLiteralDecode.ret: |
423 | .LzmaLiteralDecode.ret: |
424 | mov al, cl |
424 | mov al, cl |
425 | pop ecx |
425 | pop ecx |
426 | ret |
426 | ret |
427 | .LzmaLiteralDecodeMatch: |
427 | .LzmaLiteralDecodeMatch: |
428 | ; in: eax->probs, dl=matchByte |
428 | ; in: eax->probs, dl=matchByte |
429 | ; out: al=byte; destroys edx |
429 | ; out: al=byte; destroys edx |
430 | push ecx |
430 | push ecx |
431 | mov ecx, 1 |
431 | mov ecx, 1 |
432 | .LzmaLiteralDecodeMatch.1: |
432 | .LzmaLiteralDecodeMatch.1: |
433 | add dl, dl |
433 | add dl, dl |
434 | setc ch |
434 | setc ch |
435 | push eax |
435 | push eax |
436 | lea eax, [eax+ecx*4+0x100*4] |
436 | lea eax, [eax+ecx*4+0x100*4] |
437 | call .RangeDecoderBitDecode |
437 | call .RangeDecoderBitDecode |
438 | pop eax |
438 | pop eax |
439 | adc cl, cl |
439 | adc cl, cl |
440 | jc .LzmaLiteralDecode.ret |
440 | jc .LzmaLiteralDecode.ret |
441 | xor ch, cl |
441 | xor ch, cl |
442 | test ch, 1 |
442 | test ch, 1 |
443 | mov ch, 0 |
443 | mov ch, 0 |
444 | jnz @b |
444 | jnz @b |
445 | jmp .LzmaLiteralDecodeMatch.1 |
445 | jmp .LzmaLiteralDecodeMatch.1 |
446 | 446 | ||
447 | .LzmaLenDecode: |
447 | .LzmaLenDecode: |
448 | ; in: eax->prob, edx=posState |
448 | ; in: eax->prob, edx=posState |
449 | ; out: ecx=len |
449 | ; out: ecx=len |
450 | push eax |
450 | push eax |
451 | add eax, .LenChoice*4 |
451 | add eax, .LenChoice*4 |
452 | call .RangeDecoderBitDecode |
452 | call .RangeDecoderBitDecode |
453 | pop eax |
453 | pop eax |
454 | jnc .0 |
454 | jnc .0 |
455 | push eax |
455 | push eax |
456 | add eax, .LenChoice2*4 |
456 | add eax, .LenChoice2*4 |
457 | call .RangeDecoderBitDecode |
457 | call .RangeDecoderBitDecode |
458 | pop eax |
458 | pop eax |
459 | jc @f |
459 | jc @f |
460 | mov ecx, .kLenNumMidBits |
460 | mov ecx, .kLenNumMidBits |
461 | shl edx, cl |
461 | shl edx, cl |
462 | lea eax, [eax + .LenMid*4 + edx*4] |
462 | lea eax, [eax + .LenMid*4 + edx*4] |
463 | call .RangeDecoderBitTreeDecode |
463 | call .RangeDecoderBitTreeDecode |
464 | add ecx, .kLenNumLowSymbols |
464 | add ecx, .kLenNumLowSymbols |
465 | ret |
465 | ret |
466 | @@: |
466 | @@: |
467 | add eax, .LenHigh*4 |
467 | add eax, .LenHigh*4 |
468 | mov ecx, .kLenNumHighBits |
468 | mov ecx, .kLenNumHighBits |
469 | call .RangeDecoderBitTreeDecode |
469 | call .RangeDecoderBitTreeDecode |
470 | add ecx, .kLenNumLowSymbols + .kLenNumMidSymbols |
470 | add ecx, .kLenNumLowSymbols + .kLenNumMidSymbols |
471 | ret |
471 | ret |
472 | .0: |
472 | .0: |
473 | mov ecx, .kLenNumLowBits |
473 | mov ecx, .kLenNumLowBits |
474 | shl edx, cl |
474 | shl edx, cl |
475 | lea eax, [eax + .LenLow*4 + edx*4] |
475 | lea eax, [eax + .LenLow*4 + edx*4] |
476 | .RangeDecoderBitTreeDecode: |
476 | .RangeDecoderBitTreeDecode: |
477 | ; in: eax->probs,ecx=numLevels |
477 | ; in: eax->probs,ecx=numLevels |
478 | ; out: ecx=length; destroys edx |
478 | ; out: ecx=length; destroys edx |
479 | push ebx |
479 | push ebx |
480 | mov edx, 1 |
480 | mov edx, 1 |
481 | mov ebx, edx |
481 | mov ebx, edx |
482 | @@: |
482 | @@: |
483 | push eax |
483 | push eax |
484 | lea eax, [eax+edx*4] |
484 | lea eax, [eax+edx*4] |
485 | call .RangeDecoderBitDecode |
485 | call .RangeDecoderBitDecode |
486 | pop eax |
486 | pop eax |
487 | adc dl, dl |
487 | adc dl, dl |
488 | add bl, bl |
488 | add bl, bl |
489 | loop @b |
489 | loop @b |
490 | sub dl, bl |
490 | sub dl, bl |
491 | pop ebx |
491 | pop ebx |
492 | mov ecx, edx |
492 | mov ecx, edx |
493 | ret |
493 | ret |
494 | .RangeDecoderReverseBitTreeDecode: |
494 | .RangeDecoderReverseBitTreeDecode: |
495 | ; in: eax->probs,ecx=numLevels |
495 | ; in: eax->probs,ecx=numLevels |
496 | ; out: ecx=length; destroys edx |
496 | ; out: ecx=length; destroys edx |
497 | push ebx ecx |
497 | push ebx ecx |
498 | mov edx, 1 |
498 | mov edx, 1 |
499 | xor ebx, ebx |
499 | xor ebx, ebx |
500 | @@: |
500 | @@: |
501 | push eax |
501 | push eax |
502 | lea eax, [eax+edx*4] |
502 | lea eax, [eax+edx*4] |
503 | call .RangeDecoderBitDecode |
503 | call .RangeDecoderBitDecode |
504 | lahf |
504 | lahf |
505 | adc edx, edx |
505 | adc edx, edx |
506 | sahf |
506 | sahf |
507 | rcr ebx, 1 |
507 | rcr ebx, 1 |
508 | pop eax |
508 | pop eax |
509 | loop @b |
509 | loop @b |
510 | pop ecx |
510 | pop ecx |
511 | rol ebx, cl |
511 | rol ebx, cl |
512 | mov ecx, ebx |
512 | mov ecx, ebx |
513 | pop ebx |
513 | pop ebx |
514 | ret |
514 | ret |
515 | 515 | ||
516 | uglobal |
516 | uglobal |
517 | align 4 |
517 | align 4 |
518 | ;unpack.p rd unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp)) |
518 | ;unpack.p rd unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp)) |
519 | unpack.p dd ? |
519 | unpack.p dd ? |
520 | unpack.code_ dd ? |
520 | unpack.code_ dd ? |
521 | unpack.range dd ? |
521 | unpack.range dd ? |
522 | unpack.rep0 dd ? |
522 | unpack.rep0 dd ? |
523 | unpack.rep1 dd ? |
523 | unpack.rep1 dd ? |
524 | unpack.rep2 dd ? |
524 | unpack.rep2 dd ? |
525 | unpack.rep3 dd ? |
525 | unpack.rep3 dd ? |
526 | unpack.previousByte db ? |
526 | unpack.previousByte db ? |
527 | endg |
527 | endg |