1 #include "rar.hpp"
2
CopyString20(unsigned int Length,unsigned int Distance)3 void Unpack::CopyString20(unsigned int Length,unsigned int Distance)
4 {
5 LastDist=OldDist[OldDistPtr++ & 3]=Distance;
6 LastLength=Length;
7 DestUnpSize-=Length;
8
9 unsigned int DestPtr=UnpPtr-Distance;
10 if (DestPtr<MAXWINSIZE-300 && UnpPtr<MAXWINSIZE-300)
11 {
12 Window[UnpPtr++]=Window[DestPtr++];
13 Window[UnpPtr++]=Window[DestPtr++];
14 while (Length>2)
15 {
16 Length--;
17 Window[UnpPtr++]=Window[DestPtr++];
18 }
19 }
20 else
21 while (Length--)
22 {
23 Window[UnpPtr]=Window[DestPtr++ & MAXWINMASK];
24 UnpPtr=(UnpPtr+1) & MAXWINMASK;
25 }
26 }
27
28
Unpack20(bool Solid)29 void Unpack::Unpack20(bool Solid)
30 {
31 static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
32 static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
33 static int DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040};
34 static unsigned char DBits[]= {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
35 static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
36 static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6};
37 unsigned int Bits;
38
39 if (Suspended)
40 UnpPtr=WrPtr;
41 else
42 {
43 UnpInitData(Solid);
44 if (!UnpReadBuf())
45 return;
46 if (!Solid)
47 if (!ReadTables20())
48 return;
49 --DestUnpSize;
50 }
51
52 while (DestUnpSize>=0)
53 {
54 UnpPtr&=MAXWINMASK;
55
56 if (InAddr>ReadTop-30)
57 if (!UnpReadBuf())
58 break;
59 if (((WrPtr-UnpPtr) & MAXWINMASK)<270 && WrPtr!=UnpPtr)
60 {
61 OldUnpWriteBuf();
62 if (Suspended)
63 return;
64 }
65 if (UnpAudioBlock)
66 {
67 int AudioNumber=DecodeNumber(&MD[UnpCurChannel]);
68
69 if (AudioNumber==256)
70 {
71 if (!ReadTables20())
72 break;
73 continue;
74 }
75 Window[UnpPtr++]=DecodeAudio(AudioNumber);
76 if (++UnpCurChannel==UnpChannels)
77 UnpCurChannel=0;
78 --DestUnpSize;
79 continue;
80 }
81
82 int Number=DecodeNumber(&LD);
83 if (Number<256)
84 {
85 Window[UnpPtr++]=(byte)Number;
86 --DestUnpSize;
87 continue;
88 }
89 if (Number>269)
90 {
91 int Length=LDecode[Number-=270]+3;
92 if ((Bits=LBits[Number])>0)
93 {
94 Length+=getbits()>>(16-Bits);
95 addbits(Bits);
96 }
97
98 int DistNumber=DecodeNumber(&DD);
99 unsigned int Distance=DDecode[DistNumber]+1;
100 if ((Bits=DBits[DistNumber])>0)
101 {
102 Distance+=getbits()>>(16-Bits);
103 addbits(Bits);
104 }
105
106 if (Distance>=0x2000)
107 {
108 Length++;
109 if (Distance>=0x40000L)
110 Length++;
111 }
112
113 CopyString20(Length,Distance);
114 continue;
115 }
116 if (Number==269)
117 {
118 if (!ReadTables20())
119 break;
120 continue;
121 }
122 if (Number==256)
123 {
124 CopyString20(LastLength,LastDist);
125 continue;
126 }
127 if (Number<261)
128 {
129 unsigned int Distance=OldDist[(OldDistPtr-(Number-256)) & 3];
130 int LengthNumber=DecodeNumber(&RD);
131 int Length=LDecode[LengthNumber]+2;
132 if ((Bits=LBits[LengthNumber])>0)
133 {
134 Length+=getbits()>>(16-Bits);
135 addbits(Bits);
136 }
137 if (Distance>=0x101)
138 {
139 Length++;
140 if (Distance>=0x2000)
141 {
142 Length++;
143 if (Distance>=0x40000)
144 Length++;
145 }
146 }
147 CopyString20(Length,Distance);
148 continue;
149 }
150 if (Number<270)
151 {
152 unsigned int Distance=SDDecode[Number-=261]+1;
153 if ((Bits=SDBits[Number])>0)
154 {
155 Distance+=getbits()>>(16-Bits);
156 addbits(Bits);
157 }
158 CopyString20(2,Distance);
159 continue;
160 }
161 }
162 ReadLastTables();
163 OldUnpWriteBuf();
164 }
165
166
ReadTables20()167 bool Unpack::ReadTables20()
168 {
169 byte BitLength[BC20];
170 unsigned char Table[MC20*4];
171 int TableSize,N,I;
172 if (InAddr>ReadTop-25)
173 if (!UnpReadBuf())
174 return(false);
175 unsigned int BitField=getbits();
176 UnpAudioBlock=(BitField & 0x8000);
177
178 if (!(BitField & 0x4000))
179 memset(UnpOldTable20,0,sizeof(UnpOldTable20));
180 addbits(2);
181
182 if (UnpAudioBlock)
183 {
184 UnpChannels=((BitField>>12) & 3)+1;
185 if (UnpCurChannel>=UnpChannels)
186 UnpCurChannel=0;
187 addbits(2);
188 TableSize=MC20*UnpChannels;
189 }
190 else
191 TableSize=NC20+DC20+RC20;
192
193 for (I=0;I<BC20;I++)
194 {
195 BitLength[I]=(byte)(getbits() >> 12);
196 addbits(4);
197 }
198 MakeDecodeTables(BitLength,&BD,BC20);
199 I=0;
200 while (I<TableSize)
201 {
202 if (InAddr>ReadTop-5)
203 if (!UnpReadBuf())
204 return(false);
205 int Number=DecodeNumber(&BD);
206 if (Number<16)
207 {
208 Table[I]=(Number+UnpOldTable20[I]) & 0xf;
209 I++;
210 }
211 else
212 if (Number==16)
213 {
214 N=(getbits() >> 14)+3;
215 addbits(2);
216 while (N-- > 0 && I<TableSize)
217 {
218 Table[I]=Table[I-1];
219 I++;
220 }
221 }
222 else
223 {
224 if (Number==17)
225 {
226 N=(getbits() >> 13)+3;
227 addbits(3);
228 }
229 else
230 {
231 N=(getbits() >> 9)+11;
232 addbits(7);
233 }
234 while (N-- > 0 && I<TableSize)
235 Table[I++]=0;
236 }
237 }
238 if (InAddr>ReadTop)
239 return(true);
240 if (UnpAudioBlock)
241 for (I=0;I<UnpChannels;I++)
242 MakeDecodeTables(&Table[I*MC20],&MD[I],MC20);
243 else
244 {
245 MakeDecodeTables(&Table[0],&LD,NC20);
246 MakeDecodeTables(&Table[NC20],&DD,DC20);
247 MakeDecodeTables(&Table[NC20+DC20],&RD,RC20);
248 }
249 memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));
250 return(true);
251 }
252
253
ReadLastTables()254 void Unpack::ReadLastTables()
255 {
256 if (ReadTop>=InAddr+5)
257 if (UnpAudioBlock)
258 {
259 if (DecodeNumber(&MD[UnpCurChannel])==256)
260 ReadTables20();
261 }
262 else
263 if (DecodeNumber(&LD)==269)
264 ReadTables20();
265 }
266
267
UnpInitData20(int Solid)268 void Unpack::UnpInitData20(int Solid)
269 {
270 if (!Solid)
271 {
272 UnpAudioBlock=UnpChannelDelta=UnpCurChannel=0;
273 UnpChannels=1;
274
275 memset(AudV,0,sizeof(AudV));
276 memset(UnpOldTable20,0,sizeof(UnpOldTable20));
277 memset(MD,0,sizeof(MD));
278 }
279 }
280
281
DecodeAudio(int Delta)282 byte Unpack::DecodeAudio(int Delta)
283 {
284 struct AudioVariables *V=&AudV[UnpCurChannel];
285 V->ByteCount++;
286 V->D4=V->D3;
287 V->D3=V->D2;
288 V->D2=V->LastDelta-V->D1;
289 V->D1=V->LastDelta;
290 int PCh=8*V->LastChar+V->K1*V->D1+V->K2*V->D2+V->K3*V->D3+V->K4*V->D4+V->K5*UnpChannelDelta;
291 PCh=(PCh>>3) & 0xFF;
292
293 unsigned int Ch=PCh-Delta;
294
295 int D=((signed char)Delta)<<3;
296
297 V->Dif[0]+=abs(D);
298 V->Dif[1]+=abs(D-V->D1);
299 V->Dif[2]+=abs(D+V->D1);
300 V->Dif[3]+=abs(D-V->D2);
301 V->Dif[4]+=abs(D+V->D2);
302 V->Dif[5]+=abs(D-V->D3);
303 V->Dif[6]+=abs(D+V->D3);
304 V->Dif[7]+=abs(D-V->D4);
305 V->Dif[8]+=abs(D+V->D4);
306 V->Dif[9]+=abs(D-UnpChannelDelta);
307 V->Dif[10]+=abs(D+UnpChannelDelta);
308
309 UnpChannelDelta=V->LastDelta=(signed char)(Ch-V->LastChar);
310 V->LastChar=Ch;
311
312 if ((V->ByteCount & 0x1F)==0)
313 {
314 unsigned int MinDif=V->Dif[0],NumMinDif=0;
315 V->Dif[0]=0;
316 for (int I=1;I<sizeof(V->Dif)/sizeof(V->Dif[0]);I++)
317 {
318 if (V->Dif[I]<MinDif)
319 {
320 MinDif=V->Dif[I];
321 NumMinDif=I;
322 }
323 V->Dif[I]=0;
324 }
325 switch(NumMinDif)
326 {
327 case 1:
328 if (V->K1>=-16)
329 V->K1--;
330 break;
331 case 2:
332 if (V->K1<16)
333 V->K1++;
334 break;
335 case 3:
336 if (V->K2>=-16)
337 V->K2--;
338 break;
339 case 4:
340 if (V->K2<16)
341 V->K2++;
342 break;
343 case 5:
344 if (V->K3>=-16)
345 V->K3--;
346 break;
347 case 6:
348 if (V->K3<16)
349 V->K3++;
350 break;
351 case 7:
352 if (V->K4>=-16)
353 V->K4--;
354 break;
355 case 8:
356 if (V->K4<16)
357 V->K4++;
358 break;
359 case 9:
360 if (V->K5>=-16)
361 V->K5--;
362 break;
363 case 10:
364 if (V->K5<16)
365 V->K5++;
366 break;
367 }
368 }
369 return((byte)Ch);
370 }
371