OLD | NEW |
1 /* Bcj2.c -- Converter for x86 code (BCJ2) | 1 /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) |
2 2008-10-04 : Igor Pavlov : Public domain */ | 2 2015-08-01 : Igor Pavlov : Public domain */ |
3 | 3 |
| 4 #include "Precomp.h" |
| 5 |
4 #include "Bcj2.h" | 6 #include "Bcj2.h" |
5 | 7 #include "CpuArch.h" |
6 #ifdef _LZMA_PROB32 | 8 |
7 #define CProb UInt32 | |
8 #else | |
9 #define CProb UInt16 | 9 #define CProb UInt16 |
10 #endif | 10 |
11 | 11 #define kTopValue ((UInt32)1 << 24) |
12 #define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) | 12 #define kNumModelBits 11 |
13 #define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) | 13 #define kBitModelTotal (1 << kNumModelBits) |
14 | |
15 #define kNumTopBits 24 | |
16 #define kTopValue ((UInt32)1 << kNumTopBits) | |
17 | |
18 #define kNumBitModelTotalBits 11 | |
19 #define kBitModelTotal (1 << kNumBitModelTotalBits) | |
20 #define kNumMoveBits 5 | 14 #define kNumMoveBits 5 |
21 | 15 |
22 #define RC_READ_BYTE (*buffer++) | 16 #define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p-
>code < bound) |
23 #define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } | 17 #define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt
) >> kNumMoveBits)); |
24 #define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ | 18 #define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (tt
t >> kNumMoveBits)); |
25 { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE;
}} | 19 |
26 | 20 void Bcj2Dec_Init(CBcj2Dec *p) |
27 #define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code <<
8) | RC_READ_BYTE; } | |
28 | |
29 #define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt;
if (code < bound) | |
30 #define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt)
>> kNumMoveBits)); NORMALIZE; | |
31 #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >>
kNumMoveBits)); NORMALIZE; | |
32 | |
33 int Bcj2_Decode( | |
34 const Byte *buf0, SizeT size0, | |
35 const Byte *buf1, SizeT size1, | |
36 const Byte *buf2, SizeT size2, | |
37 const Byte *buf3, SizeT size3, | |
38 Byte *outBuf, SizeT outSize) | |
39 { | 21 { |
40 CProb p[256 + 2]; | 22 unsigned i; |
41 SizeT inPos = 0, outPos = 0; | 23 |
42 | 24 p->state = BCJ2_DEC_STATE_OK; |
43 const Byte *buffer, *bufferLim; | 25 p->ip = 0; |
44 UInt32 range, code; | 26 p->temp[3] = 0; |
45 Byte prevByte = 0; | 27 p->range = 0; |
46 | 28 p->code = 0; |
47 unsigned int i; | 29 for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) |
48 for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) | 30 p->probs[i] = kBitModelTotal >> 1; |
49 p[i] = kBitModelTotal >> 1; | 31 } |
50 | 32 |
51 buffer = buf3; | 33 SRes Bcj2Dec_Decode(CBcj2Dec *p) |
52 bufferLim = buffer + size3; | 34 { |
53 RC_INIT2 | 35 if (p->range <= 5) |
54 | 36 { |
55 if (outSize == 0) | 37 p->state = BCJ2_DEC_STATE_OK; |
56 return SZ_OK; | 38 for (; p->range != 5; p->range++) |
| 39 { |
| 40 if (p->range == 1 && p->code != 0) |
| 41 return SZ_ERROR_DATA; |
| 42 |
| 43 if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) |
| 44 { |
| 45 p->state = BCJ2_STREAM_RC; |
| 46 return SZ_OK; |
| 47 } |
| 48 |
| 49 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; |
| 50 } |
| 51 |
| 52 if (p->code == 0xFFFFFFFF) |
| 53 return SZ_ERROR_DATA; |
| 54 |
| 55 p->range = 0xFFFFFFFF; |
| 56 } |
| 57 else if (p->state >= BCJ2_DEC_STATE_ORIG_0) |
| 58 { |
| 59 while (p->state <= BCJ2_DEC_STATE_ORIG_3) |
| 60 { |
| 61 Byte *dest = p->dest; |
| 62 if (dest == p->destLim) |
| 63 return SZ_OK; |
| 64 *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0]; |
| 65 p->dest = dest + 1; |
| 66 } |
| 67 } |
| 68 |
| 69 /* |
| 70 if (BCJ2_IS_32BIT_STREAM(p->state)) |
| 71 { |
| 72 const Byte *cur = p->bufs[p->state]; |
| 73 if (cur == p->lims[p->state]) |
| 74 return SZ_OK; |
| 75 p->bufs[p->state] = cur + 4; |
| 76 |
| 77 { |
| 78 UInt32 val; |
| 79 Byte *dest; |
| 80 SizeT rem; |
| 81 |
| 82 p->ip += 4; |
| 83 val = GetBe32(cur) - p->ip; |
| 84 dest = p->dest; |
| 85 rem = p->destLim - dest; |
| 86 if (rem < 4) |
| 87 { |
| 88 SizeT i; |
| 89 SetUi32(p->temp, val); |
| 90 for (i = 0; i < rem; i++) |
| 91 dest[i] = p->temp[i]; |
| 92 p->dest = dest + rem; |
| 93 p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; |
| 94 return SZ_OK; |
| 95 } |
| 96 SetUi32(dest, val); |
| 97 p->temp[3] = (Byte)(val >> 24); |
| 98 p->dest = dest + 4; |
| 99 p->state = BCJ2_DEC_STATE_OK; |
| 100 } |
| 101 } |
| 102 */ |
57 | 103 |
58 for (;;) | 104 for (;;) |
59 { | 105 { |
60 Byte b; | 106 if (BCJ2_IS_32BIT_STREAM(p->state)) |
61 CProb *prob; | 107 p->state = BCJ2_DEC_STATE_OK; |
62 UInt32 bound; | 108 else |
63 UInt32 ttt; | 109 { |
64 | 110 if (p->range < kTopValue) |
65 SizeT limit = size0 - inPos; | 111 { |
66 if (outSize - outPos < limit) | 112 if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) |
67 limit = outSize - outPos; | 113 { |
68 while (limit != 0) | 114 p->state = BCJ2_STREAM_RC; |
69 { | 115 return SZ_OK; |
70 Byte b = buf0[inPos]; | 116 } |
71 outBuf[outPos++] = b; | 117 p->range <<= 8; |
72 if (IsJ(prevByte, b)) | 118 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; |
| 119 } |
| 120 |
| 121 { |
| 122 const Byte *src = p->bufs[BCJ2_STREAM_MAIN]; |
| 123 const Byte *srcLim; |
| 124 Byte *dest; |
| 125 SizeT num = p->lims[BCJ2_STREAM_MAIN] - src; |
| 126 |
| 127 if (num == 0) |
| 128 { |
| 129 p->state = BCJ2_STREAM_MAIN; |
| 130 return SZ_OK; |
| 131 } |
| 132 |
| 133 dest = p->dest; |
| 134 if (num > (SizeT)(p->destLim - dest)) |
| 135 { |
| 136 num = p->destLim - dest; |
| 137 if (num == 0) |
| 138 { |
| 139 p->state = BCJ2_DEC_STATE_ORIG; |
| 140 return SZ_OK; |
| 141 } |
| 142 } |
| 143 |
| 144 srcLim = src + num; |
| 145 |
| 146 if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80) |
| 147 *dest = src[0]; |
| 148 else for (;;) |
| 149 { |
| 150 Byte b = *src; |
| 151 *dest = b; |
| 152 if (b != 0x0F) |
| 153 { |
| 154 if ((b & 0xFE) == 0xE8) |
| 155 break; |
| 156 dest++; |
| 157 if (++src != srcLim) |
| 158 continue; |
| 159 break; |
| 160 } |
| 161 dest++; |
| 162 if (++src == srcLim) |
| 163 break; |
| 164 if ((*src & 0xF0) != 0x80) |
| 165 continue; |
| 166 *dest = *src; |
| 167 break; |
| 168 } |
| 169 |
| 170 num = src - p->bufs[BCJ2_STREAM_MAIN]; |
| 171 |
| 172 if (src == srcLim) |
| 173 { |
| 174 p->temp[3] = src[-1]; |
| 175 p->bufs[BCJ2_STREAM_MAIN] = src; |
| 176 p->ip += (UInt32)num; |
| 177 p->dest += num; |
| 178 p->state = |
| 179 p->bufs[BCJ2_STREAM_MAIN] == |
| 180 p->lims[BCJ2_STREAM_MAIN] ? |
| 181 (unsigned)BCJ2_STREAM_MAIN : |
| 182 (unsigned)BCJ2_DEC_STATE_ORIG; |
| 183 return SZ_OK; |
| 184 } |
| 185 |
| 186 { |
| 187 UInt32 bound, ttt; |
| 188 CProb *prob; |
| 189 Byte b = src[0]; |
| 190 Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]); |
| 191 |
| 192 p->temp[3] = b; |
| 193 p->bufs[BCJ2_STREAM_MAIN] = src + 1; |
| 194 num++; |
| 195 p->ip += (UInt32)num; |
| 196 p->dest += num; |
| 197 |
| 198 prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0x
E9 ? 1 : 0)); |
| 199 |
| 200 _IF_BIT_0 |
| 201 { |
| 202 _UPDATE_0 |
| 203 continue; |
| 204 } |
| 205 _UPDATE_1 |
| 206 |
| 207 } |
| 208 } |
| 209 } |
| 210 |
| 211 { |
| 212 UInt32 val; |
| 213 unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; |
| 214 const Byte *cur = p->bufs[cj]; |
| 215 Byte *dest; |
| 216 SizeT rem; |
| 217 |
| 218 if (cur == p->lims[cj]) |
| 219 { |
| 220 p->state = cj; |
73 break; | 221 break; |
74 inPos++; | 222 } |
75 prevByte = b; | 223 |
76 limit--; | 224 val = GetBe32(cur); |
77 } | 225 p->bufs[cj] = cur + 4; |
78 | 226 |
79 if (limit == 0 || outPos == outSize) | 227 p->ip += 4; |
80 break; | 228 val -= p->ip; |
81 | 229 dest = p->dest; |
82 b = buf0[inPos++]; | 230 rem = p->destLim - dest; |
83 | 231 |
84 if (b == 0xE8) | 232 if (rem < 4) |
85 prob = p + prevByte; | 233 { |
86 else if (b == 0xE9) | 234 SizeT i; |
87 prob = p + 256; | 235 SetUi32(p->temp, val); |
88 else | 236 for (i = 0; i < rem; i++) |
89 prob = p + 257; | 237 dest[i] = p->temp[i]; |
90 | 238 p->dest = dest + rem; |
91 IF_BIT_0(prob) | 239 p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; |
92 { | |
93 UPDATE_0(prob) | |
94 prevByte = b; | |
95 } | |
96 else | |
97 { | |
98 UInt32 dest; | |
99 const Byte *v; | |
100 UPDATE_1(prob) | |
101 if (b == 0xE8) | |
102 { | |
103 v = buf1; | |
104 if (size1 < 4) | |
105 return SZ_ERROR_DATA; | |
106 buf1 += 4; | |
107 size1 -= 4; | |
108 } | |
109 else | |
110 { | |
111 v = buf2; | |
112 if (size2 < 4) | |
113 return SZ_ERROR_DATA; | |
114 buf2 += 4; | |
115 size2 -= 4; | |
116 } | |
117 dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | | |
118 ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4); | |
119 outBuf[outPos++] = (Byte)dest; | |
120 if (outPos == outSize) | |
121 break; | 240 break; |
122 outBuf[outPos++] = (Byte)(dest >> 8); | 241 } |
123 if (outPos == outSize) | 242 |
124 break; | 243 SetUi32(dest, val); |
125 outBuf[outPos++] = (Byte)(dest >> 16); | 244 p->temp[3] = (Byte)(val >> 24); |
126 if (outPos == outSize) | 245 p->dest = dest + 4; |
127 break; | 246 } |
128 outBuf[outPos++] = prevByte = (Byte)(dest >> 24); | 247 } |
129 } | 248 |
130 } | 249 if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC]
) |
131 return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; | 250 { |
| 251 p->range <<= 8; |
| 252 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; |
| 253 } |
| 254 |
| 255 return SZ_OK; |
132 } | 256 } |
OLD | NEW |