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