1 #include "rar.hpp"
2
3 #include "coder.cpp"
4 #include "suballoc.cpp"
5 #include "model.cpp"
6 #ifndef SFX_MODULE
7 #include "unpack15.cpp"
8 #include "unpack20.cpp"
9 #endif
10
Unpack(ComprDataIO * DataIO)11 Unpack::Unpack(ComprDataIO *DataIO)
12 {
13 UnpIO=DataIO;
14 Window=NULL;
15 ExternalWindow=false;
16 Suspended=false;
17 UnpAllBuf=false;
18 UnpSomeRead=false;
19 }
20
21
~Unpack()22 Unpack::~Unpack()
23 {
24 if (Window!=NULL && !ExternalWindow)
25 delete[] Window;
26 InitFilters();
27 }
28
29
Init(byte * Window)30 void Unpack::Init(byte *Window)
31 {
32 if (Window==NULL)
33 {
34 Unpack::Window=new byte[MAXWINSIZE];
35 #ifndef ALLOW_EXCEPTIONS
36 if (Unpack::Window==NULL)
37 ErrHandler.MemoryError();
38 #endif
39 }
40 else
41 {
42 Unpack::Window=Window;
43 ExternalWindow=true;
44 }
45 UnpInitData(false);
46 }
47
48
DoUnpack(int Method,bool Solid)49 void Unpack::DoUnpack(int Method,bool Solid)
50 {
51 switch(Method)
52 {
53 #ifndef SFX_MODULE
54 case 15:
55 Unpack15(Solid);
56 break;
57 case 20:
58 case 26:
59 Unpack20(Solid);
60 break;
61 #endif
62 case 29:
63 Unpack29(Solid);
64 break;
65 }
66 }
67
68
InsertOldDist(unsigned int Distance)69 inline void Unpack::InsertOldDist(unsigned int Distance)
70 {
71 OldDist[3]=OldDist[2];
72 OldDist[2]=OldDist[1];
73 OldDist[1]=OldDist[0];
74 OldDist[0]=Distance;
75 }
76
77
InsertLastMatch(unsigned int Length,unsigned int Distance)78 inline void Unpack::InsertLastMatch(unsigned int Length,unsigned int Distance)
79 {
80 LastDist=Distance;
81 LastLength=Length;
82 }
83
84
CopyString(unsigned int Length,unsigned int Distance)85 void Unpack::CopyString(unsigned int Length,unsigned int Distance)
86 {
87 unsigned int DestPtr=UnpPtr-Distance;
88 if (DestPtr<MAXWINSIZE-260 && UnpPtr<MAXWINSIZE-260)
89 {
90 Window[UnpPtr++]=Window[DestPtr++];
91 while (--Length>0)
92 Window[UnpPtr++]=Window[DestPtr++];
93 }
94 else
95 while (Length--)
96 {
97 Window[UnpPtr]=Window[DestPtr++ & MAXWINMASK];
98 UnpPtr=(UnpPtr+1) & MAXWINMASK;
99 }
100 }
101
102
DecodeNumber(struct Decode * Dec)103 int Unpack::DecodeNumber(struct Decode *Dec)
104 {
105 unsigned int Bits;
106 unsigned int BitField=getbits() & 0xfffe;
107 if (BitField<Dec->DecodeLen[8])
108 if (BitField<Dec->DecodeLen[4])
109 if (BitField<Dec->DecodeLen[2])
110 if (BitField<Dec->DecodeLen[1])
111 Bits=1;
112 else
113 Bits=2;
114 else
115 if (BitField<Dec->DecodeLen[3])
116 Bits=3;
117 else
118 Bits=4;
119 else
120 if (BitField<Dec->DecodeLen[6])
121 if (BitField<Dec->DecodeLen[5])
122 Bits=5;
123 else
124 Bits=6;
125 else
126 if (BitField<Dec->DecodeLen[7])
127 Bits=7;
128 else
129 Bits=8;
130 else
131 if (BitField<Dec->DecodeLen[12])
132 if (BitField<Dec->DecodeLen[10])
133 if (BitField<Dec->DecodeLen[9])
134 Bits=9;
135 else
136 Bits=10;
137 else
138 if (BitField<Dec->DecodeLen[11])
139 Bits=11;
140 else
141 Bits=12;
142 else
143 if (BitField<Dec->DecodeLen[14])
144 if (BitField<Dec->DecodeLen[13])
145 Bits=13;
146 else
147 Bits=14;
148 else
149 Bits=15;
150
151 addbits(Bits);
152 unsigned int N=Dec->DecodePos[Bits]+((BitField-Dec->DecodeLen[Bits-1])>>(16-Bits));
153 if (N>=Dec->MaxNum)
154 N=0;
155 return(Dec->DecodeNum[N]);
156 }
157
158
Unpack29(bool Solid)159 void Unpack::Unpack29(bool Solid)
160 {
161 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};
162 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};
163 static int DDecode[DC];
164 static byte DBits[DC];
165 static int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12};
166 static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
167 static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6};
168 unsigned int Bits;
169
170 if (DDecode[1]==0)
171 {
172 int Dist=0,BitLength=0,Slot=0;
173 for (int I=0;I<sizeof(DBitLengthCounts)/sizeof(DBitLengthCounts[0]);I++,BitLength++)
174 for (int J=0;J<DBitLengthCounts[I];J++,Slot++,Dist+=(1<<BitLength))
175 {
176 DDecode[Slot]=Dist;
177 DBits[Slot]=BitLength;
178 }
179 }
180
181 FileExtracted=true;
182
183 if (!Suspended)
184 {
185 UnpInitData(Solid);
186 if (!UnpReadBuf())
187 return;
188 if ((!Solid || !TablesRead) && !ReadTables())
189 return;
190 }
191
192 if (PPMError)
193 return;
194
195 while (true)
196 {
197 UnpPtr&=MAXWINMASK;
198
199 if (InAddr>ReadBorder)
200 {
201 if (!UnpReadBuf())
202 break;
203 }
204 if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr)
205 {
206 UnpWriteBuf();
207 if (WrittenFileSize>DestUnpSize)
208 return;
209 if (Suspended)
210 {
211 FileExtracted=false;
212 return;
213 }
214 }
215 if (UnpBlockType==BLOCK_PPM)
216 {
217 int Ch=PPM.DecodeChar();
218 if (Ch==-1)
219 {
220 PPMError=true;
221 break;
222 }
223 if (Ch==PPMEscChar)
224 {
225 int NextCh=PPM.DecodeChar();
226 if (NextCh==0)
227 {
228 if (!ReadTables())
229 break;
230 continue;
231 }
232 if (NextCh==2 || NextCh==-1)
233 break;
234 if (NextCh==3)
235 {
236 if (!ReadVMCodePPM())
237 break;
238 continue;
239 }
240 if (NextCh==4)
241 {
242 unsigned int Distance=0,Length;
243 bool Failed=false;
244 for (int I=0;I<4 && !Failed;I++)
245 {
246 int Ch=PPM.DecodeChar();
247 if (Ch==-1)
248 Failed=true;
249 else
250 if (I==3)
251 Length=(byte)Ch;
252 else
253 Distance=(Distance<<8)+(byte)Ch;
254 }
255 if (Failed)
256 break;
257 CopyString(Length+32,Distance+2);
258 continue;
259 }
260 if (NextCh==5)
261 {
262 int Length=PPM.DecodeChar();
263 if (Length==-1)
264 break;
265 CopyString(Length+4,1);
266 continue;
267 }
268 }
269 Window[UnpPtr++]=Ch;
270 continue;
271 }
272
273 int Number=DecodeNumber((struct Decode *)&LD);
274 if (Number<256)
275 {
276 Window[UnpPtr++]=(byte)Number;
277 continue;
278 }
279 if (Number>=271)
280 {
281 int Length=LDecode[Number-=271]+3;
282 if ((Bits=LBits[Number])>0)
283 {
284 Length+=getbits()>>(16-Bits);
285 addbits(Bits);
286 }
287
288 int DistNumber=DecodeNumber((struct Decode *)&DD);
289 unsigned int Distance=DDecode[DistNumber]+1;
290 if ((Bits=DBits[DistNumber])>0)
291 {
292 if (DistNumber>9)
293 {
294 if (Bits>4)
295 {
296 Distance+=((getbits()>>(20-Bits))<<4);
297 addbits(Bits-4);
298 }
299 if (LowDistRepCount>0)
300 {
301 LowDistRepCount--;
302 Distance+=PrevLowDist;
303 }
304 else
305 {
306 int LowDist=DecodeNumber((struct Decode *)&LDD);
307 if (LowDist==16)
308 {
309 LowDistRepCount=LOW_DIST_REP_COUNT-1;
310 Distance+=PrevLowDist;
311 }
312 else
313 {
314 Distance+=LowDist;
315 PrevLowDist=LowDist;
316 }
317 }
318 }
319 else
320 {
321 Distance+=getbits()>>(16-Bits);
322 addbits(Bits);
323 }
324 }
325
326 if (Distance>=0x2000)
327 {
328 Length++;
329 if (Distance>=0x40000L)
330 Length++;
331 }
332
333 InsertOldDist(Distance);
334 InsertLastMatch(Length,Distance);
335 CopyString(Length,Distance);
336 continue;
337 }
338 if (Number==256)
339 {
340 if (!ReadEndOfBlock())
341 break;
342 continue;
343 }
344 if (Number==257)
345 {
346 if (!ReadVMCode())
347 break;
348 continue;
349 }
350 if (Number==258)
351 {
352 if (LastLength!=0)
353 CopyString(LastLength,LastDist);
354 continue;
355 }
356 if (Number<263)
357 {
358 int DistNum=Number-259;
359 unsigned int Distance=OldDist[DistNum];
360 for (int I=DistNum;I>0;I--)
361 OldDist[I]=OldDist[I-1];
362 OldDist[0]=Distance;
363
364 int LengthNumber=DecodeNumber((struct Decode *)&RD);
365 int Length=LDecode[LengthNumber]+2;
366 if ((Bits=LBits[LengthNumber])>0)
367 {
368 Length+=getbits()>>(16-Bits);
369 addbits(Bits);
370 }
371 InsertLastMatch(Length,Distance);
372 CopyString(Length,Distance);
373 continue;
374 }
375 if (Number<272)
376 {
377 unsigned int Distance=SDDecode[Number-=263]+1;
378 if ((Bits=SDBits[Number])>0)
379 {
380 Distance+=getbits()>>(16-Bits);
381 addbits(Bits);
382 }
383 InsertOldDist(Distance);
384 InsertLastMatch(2,Distance);
385 CopyString(2,Distance);
386 continue;
387 }
388 }
389 UnpWriteBuf();
390 }
391
392
ReadEndOfBlock()393 bool Unpack::ReadEndOfBlock()
394 {
395 unsigned int BitField=getbits();
396 bool NewTable,NewFile=false;
397 if (BitField & 0x8000)
398 {
399 NewTable=true;
400 addbits(1);
401 }
402 else
403 {
404 NewFile=true;
405 NewTable=(BitField & 0x4000);
406 addbits(2);
407 }
408 TablesRead=!NewTable;
409 return !(NewFile || NewTable && !ReadTables());
410 }
411
412
ReadVMCode()413 bool Unpack::ReadVMCode()
414 {
415 unsigned int FirstByte=getbits()>>8;
416 addbits(8);
417 int Length=(FirstByte & 7)+1;
418 if (Length==7)
419 {
420 Length=(getbits()>>8)+7;
421 addbits(8);
422 }
423 else
424 if (Length==8)
425 {
426 Length=getbits();
427 addbits(16);
428 }
429 Array<byte> VMCode(Length);
430 for (int I=0;I<Length;I++)
431 {
432 if (InAddr>=ReadTop-1 && !UnpReadBuf() && I<Length-1)
433 return(false);
434 VMCode[I]=getbits()>>8;
435 addbits(8);
436 }
437 return(AddVMCode(FirstByte,&VMCode[0],Length));
438 }
439
440
ReadVMCodePPM()441 bool Unpack::ReadVMCodePPM()
442 {
443 unsigned int FirstByte=PPM.DecodeChar();
444 if ((int)FirstByte==-1)
445 return(false);
446 int Length=(FirstByte & 7)+1;
447 if (Length==7)
448 {
449 int B1=PPM.DecodeChar();
450 if (B1==-1)
451 return(false);
452 Length=B1+7;
453 }
454 else
455 if (Length==8)
456 {
457 int B1=PPM.DecodeChar();
458 if (B1==-1)
459 return(false);
460 int B2=PPM.DecodeChar();
461 if (B2==-1)
462 return(false);
463 Length=B1*256+B2;
464 }
465 Array<byte> VMCode(Length);
466 for (int I=0;I<Length;I++)
467 {
468 int Ch=PPM.DecodeChar();
469 if (Ch==-1)
470 return(false);
471 VMCode[I]=Ch;
472 }
473 return(AddVMCode(FirstByte,&VMCode[0],Length));
474 }
475
476
AddVMCode(unsigned int FirstByte,byte * Code,int CodeSize)477 bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize)
478 {
479 BitInput Inp;
480 Inp.InitBitInput();
481 memcpy(Inp.InBuf,Code,Min(BitInput::MAX_SIZE,CodeSize));
482 VM.Init();
483
484 uint FiltPos;
485 if (FirstByte & 0x80)
486 {
487 FiltPos=RarVM::ReadData(Inp);
488 if (FiltPos==0)
489 InitFilters();
490 else
491 FiltPos--;
492 }
493 else
494 FiltPos=LastFilter;
495 if (FiltPos>Filters.Size() || FiltPos>OldFilterLengths.Size())
496 return(false);
497 LastFilter=FiltPos;
498 bool NewFilter=(FiltPos==Filters.Size());
499
500 UnpackFilter *Filter;
501 if (NewFilter)
502 {
503 Filters.Add(1);
504 Filters[Filters.Size()-1]=Filter=new UnpackFilter;
505 OldFilterLengths.Add(1);
506 Filter->ExecCount=0;
507 }
508 else
509 {
510 Filter=Filters[FiltPos];
511 Filter->ExecCount++;
512 }
513
514 UnpackFilter *StackFilter=new UnpackFilter;
515
516 int EmptyCount=0;
517 for (int I=0;I<PrgStack.Size();I++)
518 {
519 PrgStack[I-EmptyCount]=PrgStack[I];
520 if (PrgStack[I]==NULL)
521 EmptyCount++;
522 if (EmptyCount>0)
523 PrgStack[I]=NULL;
524 }
525 if (EmptyCount==0)
526 {
527 PrgStack.Add(1);
528 EmptyCount=1;
529 }
530 int StackPos=PrgStack.Size()-EmptyCount;
531 PrgStack[StackPos]=StackFilter;
532 StackFilter->ExecCount=Filter->ExecCount;
533
534 uint BlockStart=RarVM::ReadData(Inp);
535 if (FirstByte & 0x40)
536 BlockStart+=258;
537 StackFilter->BlockStart=(BlockStart+UnpPtr)&MAXWINMASK;
538 if (FirstByte & 0x20)
539 StackFilter->BlockLength=RarVM::ReadData(Inp);
540 else
541 StackFilter->BlockLength=FiltPos<OldFilterLengths.Size() ? OldFilterLengths[FiltPos]:0;
542 StackFilter->NextWindow=WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MAXWINMASK)<=BlockStart;
543
544 // DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x BlockStart=%08x",UnpPtr,WrPtr,BlockStart);
545
546 OldFilterLengths[FiltPos]=StackFilter->BlockLength;
547
548 memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR));
549 StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR;
550 StackFilter->Prg.InitR[4]=StackFilter->BlockLength;
551 StackFilter->Prg.InitR[5]=StackFilter->ExecCount;
552 if (FirstByte & 0x10)
553 {
554 unsigned int InitMask=Inp.fgetbits()>>9;
555 Inp.faddbits(7);
556 for (int I=0;I<7;I++)
557 if (InitMask & (1<<I))
558 StackFilter->Prg.InitR[I]=RarVM::ReadData(Inp);
559 }
560 if (NewFilter)
561 {
562 uint VMCodeSize=RarVM::ReadData(Inp);
563 if (VMCodeSize>=0x10000 || VMCodeSize==0)
564 return(false);
565 Array<byte> VMCode(VMCodeSize);
566 for (int I=0;I<VMCodeSize;I++)
567 {
568 VMCode[I]=Inp.fgetbits()>>8;
569 Inp.faddbits(8);
570 }
571 VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);
572 }
573 StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0];
574 StackFilter->Prg.CmdCount=Filter->Prg.CmdCount;
575
576 int StaticDataSize=Filter->Prg.StaticData.Size();
577 if (StaticDataSize>0 && StaticDataSize<VM_GLOBALMEMSIZE)
578 {
579 StackFilter->Prg.StaticData.Add(StaticDataSize);
580 memcpy(&StackFilter->Prg.StaticData[0],&Filter->Prg.StaticData[0],StaticDataSize);
581 }
582
583 if (StackFilter->Prg.GlobalData.Size()<VM_FIXEDGLOBALSIZE)
584 {
585 StackFilter->Prg.GlobalData.Reset();
586 StackFilter->Prg.GlobalData.Add(VM_FIXEDGLOBALSIZE);
587 }
588 byte *GlobalData=&StackFilter->Prg.GlobalData[0];
589 for (int I=0;I<7;I++)
590 VM.SetValue((uint *)&GlobalData[I*4],StackFilter->Prg.InitR[I]);
591 VM.SetValue((uint *)&GlobalData[0x1c],StackFilter->BlockLength);
592 VM.SetValue((uint *)&GlobalData[0x20],0);
593 VM.SetValue((uint *)&GlobalData[0x2c],StackFilter->ExecCount);
594 memset(&GlobalData[0x30],0,16);
595
596 if (FirstByte & 8)
597 {
598 uint DataSize=RarVM::ReadData(Inp);
599 if (DataSize>=0x10000)
600 return(false);
601 unsigned int CurSize=StackFilter->Prg.GlobalData.Size();
602 if (CurSize<DataSize+VM_FIXEDGLOBALSIZE)
603 StackFilter->Prg.GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE-CurSize);
604 byte *GlobalData=&StackFilter->Prg.GlobalData[VM_FIXEDGLOBALSIZE];
605 for (int I=0;I<DataSize;I++)
606 {
607 GlobalData[I]=Inp.fgetbits()>>8;
608 Inp.faddbits(8);
609 }
610 }
611 return(true);
612 }
613
614
UnpReadBuf()615 bool Unpack::UnpReadBuf()
616 {
617 int DataSize=ReadTop-InAddr;
618 if (DataSize<0)
619 return(false);
620 if (InAddr>BitInput::MAX_SIZE/2)
621 {
622 if (DataSize>0)
623 memmove(InBuf,InBuf+InAddr,DataSize);
624 InAddr=0;
625 ReadTop=DataSize;
626 }
627 else
628 DataSize=ReadTop;
629 int ReadCode=UnpIO->UnpRead(InBuf+DataSize,(BitInput::MAX_SIZE-DataSize)&~0xf);
630 if (ReadCode>0)
631 ReadTop+=ReadCode;
632 ReadBorder=ReadTop-30;
633 return(ReadCode!=-1);
634 }
635
636
UnpWriteBuf()637 void Unpack::UnpWriteBuf()
638 {
639 unsigned int WrittenBorder=WrPtr;
640 unsigned int WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
641 for (int I=0;I<PrgStack.Size();I++)
642 {
643 UnpackFilter *flt=PrgStack[I];
644 if (flt==NULL)
645 continue;
646 if (flt->NextWindow)
647 {
648 flt->NextWindow=false;
649 continue;
650 }
651 unsigned int BlockStart=flt->BlockStart;
652 unsigned int BlockLength=flt->BlockLength;
653 if (((BlockStart-WrittenBorder)&MAXWINMASK)<WriteSize)
654 {
655 if (WrittenBorder!=BlockStart)
656 {
657 UnpWriteArea(WrittenBorder,BlockStart);
658 WrittenBorder=BlockStart;
659 WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
660 }
661 if (BlockLength<=WriteSize)
662 {
663 unsigned int BlockEnd=(BlockStart+BlockLength)&MAXWINMASK;
664 if (BlockStart<BlockEnd || BlockEnd==0)
665 VM.SetMemory(0,Window+BlockStart,BlockLength);
666 else
667 {
668 unsigned int FirstPartLength=MAXWINSIZE-BlockStart;
669 VM.SetMemory(0,Window+BlockStart,FirstPartLength);
670 VM.SetMemory(FirstPartLength,Window,BlockEnd);
671 }
672 VM_PreparedProgram *Prg=&flt->Prg;
673 ExecuteCode(Prg);
674
675 byte *FilteredData=Prg->FilteredData;
676 unsigned int FilteredDataSize=Prg->FilteredDataSize;
677
678 delete PrgStack[I];
679 PrgStack[I]=NULL;
680 while (I+1<PrgStack.Size())
681 {
682 UnpackFilter *NextFilter=PrgStack[I+1];
683 if (NextFilter==NULL || NextFilter->BlockStart!=BlockStart ||
684 NextFilter->BlockLength!=FilteredDataSize || NextFilter->NextWindow)
685 break;
686 VM.SetMemory(0,FilteredData,FilteredDataSize);
687 VM_PreparedProgram *NextPrg=&PrgStack[I+1]->Prg;
688 ExecuteCode(NextPrg);
689 FilteredData=NextPrg->FilteredData;
690 FilteredDataSize=NextPrg->FilteredDataSize;
691 I++;
692 delete PrgStack[I];
693 PrgStack[I]=NULL;
694 }
695 UnpIO->UnpWrite(FilteredData,FilteredDataSize);
696 UnpSomeRead=true;
697 WrittenFileSize+=FilteredDataSize;
698 WrittenBorder=BlockEnd;
699 WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
700 }
701 else
702 {
703 for (int J=I;J<PrgStack.Size();J++)
704 {
705 UnpackFilter *flt=PrgStack[J];
706 if (flt!=NULL && flt->NextWindow)
707 flt->NextWindow=false;
708 }
709 WrPtr=WrittenBorder;
710 return;
711 }
712 }
713 }
714
715 UnpWriteArea(WrittenBorder,UnpPtr);
716 WrPtr=UnpPtr;
717 }
718
719
ExecuteCode(VM_PreparedProgram * Prg)720 void Unpack::ExecuteCode(VM_PreparedProgram *Prg)
721 {
722 if (Prg->GlobalData.Size()>0)
723 {
724 Prg->InitR[6]=int64to32(WrittenFileSize);
725 VM.SetValue((uint *)&Prg->GlobalData[0x24],int64to32(WrittenFileSize));
726 VM.SetValue((uint *)&Prg->GlobalData[0x28],int64to32(WrittenFileSize>>32));
727 VM.Execute(Prg);
728 }
729 }
730
731
UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr)732 void Unpack::UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr)
733 {
734 if (EndPtr!=StartPtr)
735 UnpSomeRead=true;
736 if (EndPtr<StartPtr)
737 {
738 UnpWriteData(&Window[StartPtr],-StartPtr & MAXWINMASK);
739 UnpWriteData(Window,EndPtr);
740 UnpAllBuf=true;
741 }
742 else
743 UnpWriteData(&Window[StartPtr],EndPtr-StartPtr);
744 }
745
746
UnpWriteData(byte * Data,int Size)747 void Unpack::UnpWriteData(byte *Data,int Size)
748 {
749 if (WrittenFileSize>=DestUnpSize)
750 return;
751 int WriteSize=Size;
752 Int64 LeftToWrite=DestUnpSize-WrittenFileSize;
753 if (WriteSize>LeftToWrite)
754 WriteSize=int64to32(LeftToWrite);
755 UnpIO->UnpWrite(Data,WriteSize);
756 WrittenFileSize+=Size;
757 }
758
759
ReadTables()760 bool Unpack::ReadTables()
761 {
762 byte BitLength[BC];
763 unsigned char Table[HUFF_TABLE_SIZE];
764 if (InAddr>ReadTop-25)
765 if (!UnpReadBuf())
766 return(false);
767 faddbits((8-InBit)&7);
768 unsigned int BitField=fgetbits();
769 if (BitField & 0x8000)
770 {
771 UnpBlockType=BLOCK_PPM;
772 return(PPM.DecodeInit(this,PPMEscChar));
773 }
774 UnpBlockType=BLOCK_LZ;
775
776 PrevLowDist=0;
777 LowDistRepCount=0;
778
779 if (!(BitField & 0x4000))
780 memset(UnpOldTable,0,sizeof(UnpOldTable));
781 faddbits(2);
782
783 for (int I=0;I<BC;I++)
784 {
785 int Length=(byte)(fgetbits() >> 12);
786 faddbits(4);
787 if (Length==15)
788 {
789 int ZeroCount=(byte)(fgetbits() >> 12);
790 faddbits(4);
791 if (ZeroCount==0)
792 BitLength[I]=15;
793 else
794 {
795 ZeroCount+=2;
796 while (ZeroCount-- > 0 && I<sizeof(BitLength)/sizeof(BitLength[0]))
797 BitLength[I++]=0;
798 I--;
799 }
800 }
801 else
802 BitLength[I]=Length;
803 }
804 MakeDecodeTables(BitLength,(struct Decode *)&BD,BC);
805
806 const int TableSize=HUFF_TABLE_SIZE;
807 for (int I=0;I<TableSize;)
808 {
809 if (InAddr>ReadTop-5)
810 if (!UnpReadBuf())
811 return(false);
812 int Number=DecodeNumber((struct Decode *)&BD);
813 if (Number<16)
814 {
815 Table[I]=(Number+UnpOldTable[I]) & 0xf;
816 I++;
817 }
818 else
819 if (Number<18)
820 {
821 int N;
822 if (Number==16)
823 {
824 N=(fgetbits() >> 13)+3;
825 faddbits(3);
826 }
827 else
828 {
829 N=(fgetbits() >> 9)+11;
830 faddbits(7);
831 }
832 while (N-- > 0 && I<TableSize)
833 {
834 Table[I]=Table[I-1];
835 I++;
836 }
837 }
838 else
839 {
840 int N;
841 if (Number==18)
842 {
843 N=(fgetbits() >> 13)+3;
844 faddbits(3);
845 }
846 else
847 {
848 N=(fgetbits() >> 9)+11;
849 faddbits(7);
850 }
851 while (N-- > 0 && I<TableSize)
852 Table[I++]=0;
853 }
854 }
855 TablesRead=true;
856 if (InAddr>ReadTop)
857 return(false);
858 MakeDecodeTables(&Table[0],(struct Decode *)&LD,NC);
859 MakeDecodeTables(&Table[NC],(struct Decode *)&DD,DC);
860 MakeDecodeTables(&Table[NC+DC],(struct Decode *)&LDD,LDC);
861 MakeDecodeTables(&Table[NC+DC+LDC],(struct Decode *)&RD,RC);
862 memcpy(UnpOldTable,Table,sizeof(UnpOldTable));
863 return(true);
864 }
865
866
UnpInitData(int Solid)867 void Unpack::UnpInitData(int Solid)
868 {
869 if (!Solid)
870 {
871 TablesRead=false;
872 memset(OldDist,0,sizeof(OldDist));
873 OldDistPtr=0;
874 LastDist=LastLength=0;
875 // memset(Window,0,MAXWINSIZE);
876 memset(UnpOldTable,0,sizeof(UnpOldTable));
877 UnpPtr=WrPtr=0;
878 PPMEscChar=2;
879
880 InitFilters();
881 }
882 InitBitInput();
883 PPMError=false;
884 WrittenFileSize=0;
885 ReadTop=0;
886 ReadBorder=0;
887 #ifndef SFX_MODULE
888 UnpInitData20(Solid);
889 #endif
890 }
891
892
InitFilters()893 void Unpack::InitFilters()
894 {
895 OldFilterLengths.Reset();
896 LastFilter=0;
897
898 for (int I=0;I<Filters.Size();I++)
899 delete Filters[I];
900 Filters.Reset();
901 for (int I=0;I<PrgStack.Size();I++)
902 delete PrgStack[I];
903 PrgStack.Reset();
904 }
905
906
MakeDecodeTables(unsigned char * LenTab,struct Decode * Dec,int Size)907 void Unpack::MakeDecodeTables(unsigned char *LenTab,struct Decode *Dec,int Size)
908 {
909 int LenCount[16],TmpPos[16],I;
910 long M,N;
911 memset(LenCount,0,sizeof(LenCount));
912 memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
913 for (I=0;I<Size;I++)
914 LenCount[LenTab[I] & 0xF]++;
915
916 LenCount[0]=0;
917 for (TmpPos[0]=Dec->DecodePos[0]=Dec->DecodeLen[0]=0,N=0,I=1;I<16;I++)
918 {
919 N=2*(N+LenCount[I]);
920 M=N<<(15-I);
921 if (M>0xFFFF)
922 M=0xFFFF;
923 Dec->DecodeLen[I]=(unsigned int)M;
924 TmpPos[I]=Dec->DecodePos[I]=Dec->DecodePos[I-1]+LenCount[I-1];
925 }
926
927 for (I=0;I<Size;I++)
928 if (LenTab[I]!=0)
929 Dec->DecodeNum[TmpPos[LenTab[I] & 0xF]++]=I;
930 Dec->MaxNum=Size;
931 }
932