add a libcrypt warning
[pcsx_rearmed.git] / deps / libchdr / deps / lzma-22.01 / src / Bcj2.c
CommitLineData
9e052883 1/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)\r
22021-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
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[(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