Merge pull request #461 from negativeExponent/libchdr
[pcsx_rearmed.git] / deps / lzma-16.04 / C / Bcj2.c
CommitLineData
ce188d4d 1/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)\r
22015-08-01 : 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
20void 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
33SRes 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[p->state++ - BCJ2_DEC_STATE_ORIG_0];\r
65 p->dest = dest + 1;\r
66 }\r
67 }\r
68\r
69 /*\r
70 if (BCJ2_IS_32BIT_STREAM(p->state))\r
71 {\r
72 const Byte *cur = p->bufs[p->state];\r
73 if (cur == p->lims[p->state])\r
74 return SZ_OK;\r
75 p->bufs[p->state] = cur + 4;\r
76 \r
77 {\r
78 UInt32 val;\r
79 Byte *dest;\r
80 SizeT rem;\r
81 \r
82 p->ip += 4;\r
83 val = GetBe32(cur) - p->ip;\r
84 dest = p->dest;\r
85 rem = p->destLim - dest;\r
86 if (rem < 4)\r
87 {\r
88 SizeT i;\r
89 SetUi32(p->temp, val);\r
90 for (i = 0; i < rem; i++)\r
91 dest[i] = p->temp[i];\r
92 p->dest = dest + rem;\r
93 p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;\r
94 return SZ_OK;\r
95 }\r
96 SetUi32(dest, val);\r
97 p->temp[3] = (Byte)(val >> 24);\r
98 p->dest = dest + 4;\r
99 p->state = BCJ2_DEC_STATE_OK;\r
100 }\r
101 }\r
102 */\r
103\r
104 for (;;)\r
105 {\r
106 if (BCJ2_IS_32BIT_STREAM(p->state))\r
107 p->state = BCJ2_DEC_STATE_OK;\r
108 else\r
109 {\r
110 if (p->range < kTopValue)\r
111 {\r
112 if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])\r
113 {\r
114 p->state = BCJ2_STREAM_RC;\r
115 return SZ_OK;\r
116 }\r
117 p->range <<= 8;\r
118 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;\r
119 }\r
120\r
121 {\r
122 const Byte *src = p->bufs[BCJ2_STREAM_MAIN];\r
123 const Byte *srcLim;\r
124 Byte *dest;\r
125 SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;\r
126 \r
127 if (num == 0)\r
128 {\r
129 p->state = BCJ2_STREAM_MAIN;\r
130 return SZ_OK;\r
131 }\r
132 \r
133 dest = p->dest;\r
134 if (num > (SizeT)(p->destLim - dest))\r
135 {\r
136 num = p->destLim - dest;\r
137 if (num == 0)\r
138 {\r
139 p->state = BCJ2_DEC_STATE_ORIG;\r
140 return SZ_OK;\r
141 }\r
142 }\r
143 \r
144 srcLim = src + num;\r
145\r
146 if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)\r
147 *dest = src[0];\r
148 else for (;;)\r
149 {\r
150 Byte b = *src;\r
151 *dest = b;\r
152 if (b != 0x0F)\r
153 {\r
154 if ((b & 0xFE) == 0xE8)\r
155 break;\r
156 dest++;\r
157 if (++src != srcLim)\r
158 continue;\r
159 break;\r
160 }\r
161 dest++;\r
162 if (++src == srcLim)\r
163 break;\r
164 if ((*src & 0xF0) != 0x80)\r
165 continue;\r
166 *dest = *src;\r
167 break;\r
168 }\r
169 \r
170 num = src - p->bufs[BCJ2_STREAM_MAIN];\r
171 \r
172 if (src == srcLim)\r
173 {\r
174 p->temp[3] = src[-1];\r
175 p->bufs[BCJ2_STREAM_MAIN] = src;\r
176 p->ip += (UInt32)num;\r
177 p->dest += num;\r
178 p->state =\r
179 p->bufs[BCJ2_STREAM_MAIN] ==\r
180 p->lims[BCJ2_STREAM_MAIN] ?\r
181 (unsigned)BCJ2_STREAM_MAIN :\r
182 (unsigned)BCJ2_DEC_STATE_ORIG;\r
183 return SZ_OK;\r
184 }\r
185 \r
186 {\r
187 UInt32 bound, ttt;\r
188 CProb *prob;\r
189 Byte b = src[0];\r
190 Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);\r
191 \r
192 p->temp[3] = b;\r
193 p->bufs[BCJ2_STREAM_MAIN] = src + 1;\r
194 num++;\r
195 p->ip += (UInt32)num;\r
196 p->dest += num;\r
197 \r
198 prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));\r
199 \r
200 _IF_BIT_0\r
201 {\r
202 _UPDATE_0\r
203 continue;\r
204 }\r
205 _UPDATE_1\r
206 \r
207 }\r
208 }\r
209 }\r
210\r
211 {\r
212 UInt32 val;\r
213 unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;\r
214 const Byte *cur = p->bufs[cj];\r
215 Byte *dest;\r
216 SizeT rem;\r
217 \r
218 if (cur == p->lims[cj])\r
219 {\r
220 p->state = cj;\r
221 break;\r
222 }\r
223 \r
224 val = GetBe32(cur);\r
225 p->bufs[cj] = cur + 4;\r
226\r
227 p->ip += 4;\r
228 val -= p->ip;\r
229 dest = p->dest;\r
230 rem = p->destLim - dest;\r
231 \r
232 if (rem < 4)\r
233 {\r
234 SizeT i;\r
235 SetUi32(p->temp, val);\r
236 for (i = 0; i < rem; i++)\r
237 dest[i] = p->temp[i];\r
238 p->dest = dest + rem;\r
239 p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;\r
240 break;\r
241 }\r
242 \r
243 SetUi32(dest, val);\r
244 p->temp[3] = (Byte)(val >> 24);\r
245 p->dest = dest + 4;\r
246 }\r
247 }\r
248\r
249 if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])\r
250 {\r
251 p->range <<= 8;\r
252 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;\r
253 }\r
254\r
255 return SZ_OK;\r
256}\r