home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vp21beta.zip / AEXMPSRC.RAR / UNRAR / UNPACK.C next >
C/C++ Source or Header  |  2000-08-15  |  17KB  |  753 lines

  1. /******    *****   ******
  2.  **   **  **   **  **   **      unRAR utility version 1.01
  3.  ******   *******  ******       ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4.  **   **  **   **  **   **         FREE portable version
  5.  **   **  **   **  **   **         ~~~~~~~~~~~~~~~~~~~~~
  6.  
  7.      Unpacking algorithm procedures
  8.  
  9.    YOU DO NOT NEED TO CHANGE THERE ANYTHING.
  10. */
  11.  
  12. void MakeTbl();               /* Makes Huffman table */
  13. void AddBit();                /* Shift buffer pointer to NBits */
  14. void CopyString();            /* string copy */
  15. void ShortLZ();               /* unpacks short, near and special LZ codes */
  16. void LongLZ();                /* unpacks long and far LZ codes */
  17. void HuffDecode();            /* Huffman decoding */
  18. int  UnpWriteBuf();           /* writes output buffer */
  19. int  UnpReadBuf();            /* reads output buffer */
  20. void GetFlagsBuf();           /* gets flag byte */
  21. void UnpInitData();           /* reset initial data */
  22. void InitHuff();              /* initializing Huffman tables */
  23. void CorrHuff();              /* Huffman table correction in case of overflow */
  24. void CreateEncTbl();          /* create decoding tables */
  25. void CreateOneTbl();          /* subfunction of previous */
  26. int  unpack();                /* unpacking procedure itself */
  27.  
  28. #define     SUSPEND     1
  29. #define     SIZE_PBUF   0x2000
  30. #define     FIRST       1
  31. #define     NEXT        2
  32. #define     UNP_MEMORY  0x10010L+sizeof(struct UnpData)+ \
  33.                         sizeof(struct DecodeTables)+SIZE_PBUF
  34.  
  35.  
  36. UWORD hcdsh1[]={ 0x0001,0xa003,0xd004,0xe004,0xf005,0xf806,0xfc07,0xfe08,
  37.                  0xff08,0xc004,0x8004,0x9005,0x9806,0x9c06,0 };
  38.  
  39. UWORD hcdsh2[]={ 0x0002,0x4003,0x6003,0xa003,0xd004,0xe004,0xf005,0xf806,
  40.                  0xfc06,0xc004,0x8004,0x9005,0x9806,0x9c06,0 };
  41.  
  42. UWORD hcdsh3[]={ 0x0001,0xa004,0xd004,0xe004,0xf005,0xf806,0xfc07,0xfe08,
  43.                  0xff08,0xc004,0x8004,0x9005,0x9806,0x9c06,0xb004,0 };
  44.  
  45. UWORD hcdsh4[]={ 0x0002,0x4003,0x6003,0xa004,0xd004,0xe004,0xf005,0xf806,
  46.                  0xfc06,0xc004,0x8004,0x9005,0x9806,0x9c06,0xb004,0 };
  47.  
  48. UWORD hcdln0[]={ 0x8001,0x4002,0x2003,0x1004,0x0805,0x0406,0x0207,0x0108,
  49.                  0x0008,0 };
  50.  
  51. UWORD hcdln1[258],hcdln2[258];
  52. UWORD hcode0[258],hcode1[258],hcode2[258],hcode3[258],hcode4[258];
  53.  
  54. struct MakeHuffTabs
  55. {
  56.   UWORD *Table;
  57.   UBYTE HuffCodeCount[12];
  58. } MakeTab[]={
  59.  {hcdln1,{0  ,2  ,1  ,2  ,2  ,4   ,5   ,4   ,4   ,8   ,0   ,224}},
  60.  {hcdln2,{0  ,0  ,5  ,2  ,2  ,4   ,5   ,4   ,4   ,8   ,2   ,220}},
  61.  {hcode0,{0  ,0  ,0  ,8  ,8  ,8   ,9   ,0   ,0   ,0   ,0   ,224}},
  62.  {hcode1,{0  ,0  ,0  ,0  ,4  ,40  ,16  ,16  ,4   ,0   ,47  ,130}},
  63.  {hcode2,{0  ,0  ,0  ,0  ,2  ,5   ,46  ,64  ,116 ,24  ,0   ,0  }},
  64.  {hcode3,{0  ,0  ,0  ,0  ,0  ,2   ,14  ,202 ,33  ,6   ,0   ,0  }},
  65.  {hcode4,{0  ,0  ,0  ,0  ,0  ,0   ,0   ,255 ,2   ,0   ,0   ,0  }}};
  66.  
  67.  
  68. SDWORD DestUnpSize=0;
  69. UBYTE  FlagBuf;
  70. UWORD  InAdr,OutAdr;
  71.  
  72. unsigned int Suspend=0;
  73. unsigned int NumBit;
  74. unsigned int LCount;
  75. int FlagsCnt;
  76.  
  77. struct UnpData
  78. {
  79.   UWORD ChSet[256];
  80.   UBYTE Place[256];
  81.   UBYTE NToPl[256];
  82.  
  83.   UBYTE ChSetA[256];
  84.   UBYTE PlaceA[256];
  85.  
  86.   UWORD ChSetB[256];
  87.   UBYTE PlaceB[256];
  88.   UBYTE NToPlB[256];
  89.  
  90.   UWORD ChSetC[256];
  91.   UBYTE PlaceC[256];
  92.   UBYTE NToPlC[256];
  93.  
  94.   UWORD AvrPlc;
  95.   UWORD AvrPlcB;
  96.   UWORD AvrLn1;
  97.   UWORD AvrLn2;
  98.   UWORD AvrLn3;
  99.  
  100.   UBYTE NumHuf;
  101.   UBYTE StMode;
  102.  
  103.   UWORD Nhfb;
  104.   UWORD Nlzb;
  105.  
  106.   UWORD MaxDist3;
  107.   UBYTE Buf60;
  108.   UWORD WrAddr;
  109.   UWORD SomeRd;
  110.   UWORD UnpAllBuf;
  111.  
  112.   UWORD LastDist;
  113.   UWORD LastLen;
  114.   UWORD OldDist[4];
  115.   UWORD OldDistNum;
  116. } *D;
  117.  
  118.  
  119. struct DecodeTables
  120. {
  121.   UBYTE ECDSH1[256];
  122.   UBYTE ECDSH2[256];
  123.   UBYTE ECDSH3[256];
  124.   UBYTE ECDSH4[256];
  125.  
  126.   UBYTE ECDLN0[256];
  127.   UBYTE ECDLN1[4096];
  128.   UBYTE ECDLN2[4096];
  129.   UBYTE ECODE0[4096];
  130.   UBYTE ECODE1[4096];
  131.   UBYTE ECODE2[1024];
  132.   UBYTE ECODE3[1024];
  133.   UBYTE ECODE4[1024];
  134.   UBYTE NCDSH1[16];
  135.   UBYTE NCDSH2[16];
  136.   UBYTE NCDSH3[16];
  137.   UBYTE NCDSH4[16];
  138.   UBYTE NCDLN0[256];
  139.   UBYTE NCDLN1[256];
  140.   UBYTE NCDLN2[256];
  141.   UBYTE NCODE0[257];
  142.   UBYTE NCODE1[257];
  143.   UBYTE NCODE2[257];
  144.   UBYTE NCODE3[257];
  145.   UBYTE NCODE4[257];
  146. } *T;
  147.  
  148. UBYTE *PackBuf;
  149. HPBYTE UnpBuf;
  150.  
  151. int (* UnpReadFn)();
  152. int (* UnpWriteFn)();
  153.  
  154.  
  155. #define GetField() ((UWORD)((((UDWORD)PackBuf[InAdr] << 16) |         \
  156.                    ((UWORD)PackBuf[InAdr+1] << 8) | PackBuf[InAdr+2]) \
  157.                     >> (8-NumBit)))
  158.  
  159. void AddBit(NBits)
  160. unsigned int NBits;
  161. {
  162.   InAdr += (NumBit+NBits) >> 3;
  163.   NumBit = (NumBit+NBits) & 7;
  164. }
  165.  
  166. void CopyString(Distance,Length)
  167. UWORD Distance;
  168. unsigned int Length;
  169. {
  170.   DestUnpSize-=Length;
  171.   while (Length--)
  172.   {
  173.     UnpBuf[OutAdr]=UnpBuf[(UWORD)(OutAdr-Distance)];
  174.     OutAdr++;
  175.   }
  176. }
  177.  
  178. int unpack(UnpMem,UnpRead,UnpWrite,Solid)
  179. HPBYTE UnpMem;
  180. int (* UnpRead)();
  181. int (* UnpWrite)();
  182. int Solid;
  183. {
  184.   UnpReadFn=UnpRead;
  185.   UnpWriteFn=UnpWrite;
  186.   UnpBuf=(UBYTE *)UnpMem;
  187.   PackBuf=(UBYTE *)(UnpMem+0x10000L+sizeof(struct UnpData)+sizeof(struct DecodeTables));
  188.   D=(struct UnpData *)(UnpMem+0x10000L);
  189.  
  190.   if (Suspend)
  191.     OutAdr=D->WrAddr;
  192.   else
  193.   {
  194.     UnpInitData(Solid);
  195.     if (!Solid)
  196.     {
  197.       InitHuff();
  198.       memset(UnpBuf,0,0x8000);
  199.       memset(UnpBuf+0x8000,0,0x8000);
  200.       OutAdr=0;
  201.     }
  202.     else
  203.       OutAdr=D->WrAddr;
  204.     if (--DestUnpSize < 0)
  205.       return(0);
  206.  
  207.     if (UnpReadBuf(FIRST)==-1)
  208.       return(-1);
  209.  
  210.     GetFlagsBuf();
  211.     FlagsCnt=8;
  212.   }
  213.  
  214.   while (DestUnpSize>=0)
  215.   {
  216.     if (InAdr >= SIZE_PBUF-12)
  217.       if (UnpReadBuf(NEXT)==-1)
  218.         return(-1);
  219.     if ((UWORD)(D->WrAddr - OutAdr) < 0x110 && D->WrAddr!=OutAdr)
  220.     {
  221.       if (UnpWriteBuf()==-1)
  222.         return(-1);
  223.       if (Suspend)
  224.         return(0);
  225.     }
  226.  
  227.     if (D->StMode)
  228.     {
  229.       HuffDecode();
  230.       continue;
  231.     }
  232.  
  233.     if (--FlagsCnt < 0)
  234.     {
  235.       GetFlagsBuf();
  236.       FlagsCnt=7;
  237.     }
  238.  
  239.     if (FlagBuf >= 0x80)
  240.     {
  241.       FlagBuf<<=1;
  242.       if (D->Nlzb > D->Nhfb)
  243.         LongLZ();
  244.       else
  245.         HuffDecode();
  246.     }
  247.     else
  248.     {
  249.       FlagBuf<<=1;
  250.       if (--FlagsCnt < 0)
  251.       {
  252.         GetFlagsBuf();
  253.         FlagsCnt=7;
  254.       }
  255.       if (FlagBuf >= 0x80)
  256.       {
  257.         FlagBuf<<=1;
  258.         if (D->Nlzb > D->Nhfb)
  259.           HuffDecode();
  260.         else
  261.           LongLZ();
  262.       }
  263.       else
  264.       {
  265.         FlagBuf<<=1;
  266.         ShortLZ();
  267.       }
  268.     }
  269.   }
  270.   if (UnpWriteBuf()==-1)
  271.     return(-1);
  272.   return(0);
  273. }
  274.  
  275.  
  276. void ShortLZ()
  277. {
  278.   UWORD LengthCode,SaveLength;
  279.   UBYTE LastDistance;
  280.   UWORD Distance,DistancePlace,Length;
  281.   D->NumHuf=0;
  282.   LengthCode=GetField();
  283.   if (LCount==2)
  284.   {
  285.     AddBit(1);
  286.     if (LengthCode >= 0x8000)
  287.     {
  288.       CopyString(D->LastDist,D->LastLen);
  289.       return;
  290.     }
  291.     LengthCode <<= 1;
  292.     LCount=0;
  293.   }
  294.   LengthCode >>= 8;
  295.   if (D->Buf60==0)
  296.     if (D->AvrLn1<37)
  297.     {
  298.       Length=T->ECDSH1[LengthCode];
  299.       AddBit(T->NCDSH1[Length]);
  300.     }
  301.     else
  302.     {
  303.       Length=T->ECDSH2[LengthCode];
  304.       AddBit(T->NCDSH2[Length]);
  305.     }
  306.   else
  307.     if (D->AvrLn1<37)
  308.     {
  309.       Length=T->ECDSH3[LengthCode];
  310.       AddBit(T->NCDSH3[Length]);
  311.     }
  312.     else
  313.     {
  314.       Length=T->ECDSH4[LengthCode];
  315.       AddBit(T->NCDSH4[Length]);
  316.     }
  317.  
  318.   if (Length >= 9)
  319.   {
  320.     if (Length == 9)
  321.     {
  322.       LCount++;
  323.       CopyString(D->LastDist,D->LastLen);
  324.       return;
  325.     }
  326.     if (Length == 14)
  327.     {
  328.       LCount=0;
  329.       Length=T->ECDLN2[GetField() >> 4];
  330.       AddBit(T->NCDLN2[Length]);
  331.       Length+=5;
  332.       Distance=(GetField() >> 1) | 0x8000;
  333.       AddBit(15);
  334.       D->LastLen=Length;
  335.       D->LastDist=Distance;
  336.       CopyString(Distance,Length);
  337.       return;
  338.     }
  339.  
  340.     LCount=0;
  341.     SaveLength=Length;
  342.     Distance=D->OldDist[(D->OldDistNum-(Length-9)) & 3];
  343.     Length=T->ECDLN1[GetField() >> 4];
  344.     AddBit(T->NCDLN1[Length]);
  345.     Length+=2;
  346.     if (Length==0x101 && SaveLength==10)
  347.     {
  348.       D->Buf60 ^= 1;
  349.       return;
  350.     }
  351.     if (Distance > 256)
  352.       Length++;
  353.     if (Distance > D->MaxDist3)
  354.       Length++;
  355.  
  356.     D->OldDist[D->OldDistNum++]=Distance;
  357.     D->OldDistNum = D->OldDistNum & 3;
  358.     D->LastLen=Length;
  359.     D->LastDist=Distance;
  360.     CopyString(Distance,Length);
  361.     return;
  362.   }
  363.  
  364.   LCount=0;
  365.   D->AvrLn1 += Length;
  366.   D->AvrLn1 -= D->AvrLn1 >> 4;
  367.  
  368.   DistancePlace=T->ECODE2[GetField() >> 6];
  369.   AddBit(T->NCODE2[DistancePlace]);
  370.   Distance=D->ChSetA[DistancePlace];
  371.   if (--DistancePlace != 0xFFFF)
  372.   {
  373.     D->PlaceA[Distance]--;
  374.     LastDistance=D->ChSetA[DistancePlace];
  375.     D->PlaceA[LastDistance]++;
  376.     D->ChSetA[DistancePlace+1]=LastDistance;
  377.     D->ChSetA[DistancePlace]=(UBYTE)Distance;
  378.   }
  379.   Length+=2;
  380.   D->OldDist[D->OldDistNum++] = ++Distance;
  381.   D->OldDistNum = D->OldDistNum & 3;
  382.   D->LastLen=Length;
  383.   D->LastDist=Distance;
  384.   CopyString(Distance,Length);
  385.   return;
  386. }
  387.  
  388.  
  389. void LongLZ()
  390. {
  391.   UWORD LengthCode,Length;
  392.   UWORD Distance,DistancePlace,NewDistancePlace;
  393.   UWORD oldav2,oldav3;
  394.  
  395.   D->NumHuf=0;
  396.   D->Nlzb+=16;
  397.   if (D->Nlzb > 0xff)
  398.   {
  399.     D->Nlzb=0x90;
  400.     D->Nhfb >>= 1;
  401.   }
  402.   oldav2=D->AvrLn2;
  403.   if (D->AvrLn2 >= 122)
  404.   {
  405.     Length=T->ECDLN2[GetField() >> 4];
  406.     AddBit(T->NCDLN2[Length]);
  407.   }
  408.   else
  409.     if (D->AvrLn2 >= 64)
  410.     {
  411.       Length=T->ECDLN1[GetField() >> 4];
  412.       AddBit(T->NCDLN1[Length]);
  413.     }
  414.     else
  415.     {
  416.       LengthCode=GetField();
  417.       if (LengthCode < 0x100)
  418.       {
  419.         Length=LengthCode;
  420.         AddBit(16);
  421.       }
  422.       else
  423.       {
  424.         Length=T->ECDLN0[LengthCode >> 8];
  425.         AddBit(T->NCDLN0[Length]);
  426.       }
  427.     }
  428.  
  429.   D->AvrLn2 += Length;
  430.   D->AvrLn2 -= D->AvrLn2 >> 5;
  431.   if (D->AvrPlcB > 0x28ff)
  432.   {
  433.     DistancePlace=T->ECODE2[GetField() >> 6];
  434.     AddBit(T->NCODE2[DistancePlace]);
  435.   }
  436.   else
  437.     if (D->AvrPlcB > 0x6ff)
  438.     {
  439.       DistancePlace=T->ECODE1[GetField() >> 4];
  440.       AddBit(T->NCODE1[DistancePlace]);
  441.     }
  442.     else
  443.     {
  444.       DistancePlace=T->ECODE0[GetField() >> 4];
  445.       AddBit(T->NCODE0[DistancePlace]);
  446.     }
  447.  
  448.   D->AvrPlcB += DistancePlace;
  449.   D->AvrPlcB -= D->AvrPlcB >> 8;
  450.   while (1)
  451.   {
  452.     Distance = D->ChSetB[DistancePlace];
  453.     NewDistancePlace = D->NToPlB[Distance++ & 0xff]++;
  454.     if (!(Distance & 0xff))
  455.     {
  456.       Distance-=0x100;
  457.       CorrHuff(D->ChSetB,D->NToPlB);
  458.     }
  459.     else
  460.       break;
  461.   }
  462.  
  463.   D->ChSetB[DistancePlace]=D->ChSetB[NewDistancePlace];
  464.   D->ChSetB[NewDistancePlace]=Distance;
  465.  
  466.   Distance=((UWORD)((Distance & ~0xff) | (GetField() >> 8))) >> 1;
  467.   AddBit(7);
  468.  
  469.   oldav3=D->AvrLn3;
  470.   if (Length!=1 && Length!=4)
  471.     if (Length==0 && Distance <= D->MaxDist3)
  472.     {
  473.       D->AvrLn3++;
  474.       D->AvrLn3 -= D->AvrLn3 >> 8;
  475.     }
  476.     else
  477.       if (D->AvrLn3 > 0)
  478.         D->AvrLn3--;
  479.   Length+=3;
  480.   if (Distance >= D->MaxDist3)
  481.     Length++;
  482.   if (Distance <= 256)
  483.     Length+=8;
  484.   if (oldav3 > 0xb0 || D->AvrPlc >= 0x2a00 && oldav2 < 0x40)
  485.     D->MaxDist3=0x7f00;
  486.   else
  487.     D->MaxDist3=0x2001;
  488.   D->OldDist[D->OldDistNum++]=Distance;
  489.   D->OldDistNum = D->OldDistNum & 3;
  490.   D->LastLen=Length;
  491.   D->LastDist=Distance;
  492.   CopyString(Distance,Length);
  493. }
  494.  
  495.  
  496. void HuffDecode()
  497. {
  498.   UWORD CurByte,BytePlace,NewBytePlace;
  499.   UWORD Length,Distance,Code;
  500.  
  501.   Code=GetField();
  502.  
  503.   if (D->AvrPlc > 0x75ff)
  504.   {
  505.     BytePlace=T->ECODE4[Code>>6];
  506.     if (D->StMode && BytePlace==0 && Code > 0xfff)
  507.       BytePlace=0x100;
  508.     AddBit(T->NCODE4[BytePlace]);
  509.   }
  510.   else
  511.     if (D->AvrPlc > 0x5dff)
  512.     {
  513.       BytePlace=T->ECODE3[Code>>6];
  514.       if (D->StMode && BytePlace==0 && Code > 0xfff)
  515.         BytePlace=0x100;
  516.       AddBit(T->NCODE3[BytePlace]);
  517.     }
  518.     else
  519.       if (D->AvrPlc > 0x35ff)
  520.       {
  521.         BytePlace=T->ECODE2[Code>>6];
  522.         if (D->StMode && BytePlace==0 && Code > 0xfff)
  523.           BytePlace=0x100;
  524.         AddBit(T->NCODE2[BytePlace]);
  525.       }
  526.       else
  527.         if (D->AvrPlc > 0x0dff)
  528.         {
  529.           BytePlace=T->ECODE1[Code>>4];
  530.           if (D->StMode && BytePlace==0 && Code > 0xfff)
  531.             BytePlace=0x100;
  532.           AddBit(T->NCODE1[BytePlace]);
  533.         }
  534.         else
  535.         {
  536.           BytePlace=T->ECODE0[Code>>4];
  537.           if (D->StMode && BytePlace==0 && Code > 0xfff)
  538.             BytePlace=0x100;
  539.           AddBit(T->NCODE0[BytePlace]);
  540.         }
  541.   if (D->StMode)
  542.   {
  543.     if (--BytePlace==0xFFFF)
  544.     {
  545.       Code=GetField();
  546.       AddBit(1);
  547.       if (Code >= 0x8000)
  548.       {
  549.         D->NumHuf=D->StMode=0;
  550.         return;
  551.       }
  552.       else
  553.       {
  554.         Length = (Code & 0x4000) ? 4 : 3;
  555.         Distance= T->ECODE2[(Code >> 4) & 0x3ff];
  556.         AddBit(T->NCODE2[Distance]+1);
  557.         Distance = (Distance << 5) | (GetField() >> 11);
  558.         AddBit(5);
  559.         CopyString(Distance,Length);
  560.         return;
  561.       }
  562.     }
  563.   }
  564.   else
  565.     if (D->NumHuf++ >= 16 && FlagsCnt==0)
  566.       D->StMode=1;
  567.   D->AvrPlc += BytePlace;
  568.   D->AvrPlc -= D->AvrPlc >> 8;
  569.   D->Nhfb+=16;
  570.   if (D->Nhfb > 0xff)
  571.   {
  572.     D->Nhfb=0x90;
  573.     D->Nlzb >>= 1;
  574.   }
  575.  
  576.   UnpBuf[OutAdr++]=(UBYTE)(D->ChSet[BytePlace]>>8);
  577.   DestUnpSize--;
  578.  
  579.   while (1)
  580.   {
  581.     CurByte=D->ChSet[BytePlace];
  582.     NewBytePlace=D->NToPl[CurByte++ & 0xff]++;
  583.     if ((CurByte & 0xff) > 0xa1)
  584.       CorrHuff(D->ChSet,D->NToPl);
  585.     else
  586.       break;
  587.   }
  588.  
  589.   D->ChSet[BytePlace]=D->ChSet[NewBytePlace];
  590.   D->ChSet[NewBytePlace]=CurByte;
  591. }
  592.  
  593.  
  594. int UnpWriteBuf()
  595. {
  596.   if (OutAdr<D->WrAddr)
  597.   {
  598.     if (UnpWriteFn((UBYTE *)(UnpBuf+D->WrAddr),(UWORD)-D->WrAddr)==-1 ||
  599.         UnpWriteFn((UBYTE *)UnpBuf,(UWORD)OutAdr)==-1)
  600.       return(-1);
  601.   }
  602.   else
  603.     if (UnpWriteFn((UBYTE *)(UnpBuf+D->WrAddr),(UWORD)(OutAdr-D->WrAddr))==-1)
  604.       return(-1);
  605.   D->WrAddr=OutAdr;
  606.   return(0);
  607. }
  608.  
  609.  
  610. int UnpReadBuf(NumBuf)
  611. int NumBuf;
  612. {
  613.   int ReadCode;
  614.   if (NumBuf==FIRST)
  615.     ReadCode=UnpReadFn(PackBuf,SIZE_PBUF);
  616.   else
  617.   {
  618.     memcpy(PackBuf,PackBuf+InAdr,(UWORD)(SIZE_PBUF-InAdr));
  619.     ReadCode=UnpReadFn(PackBuf+SIZE_PBUF-InAdr,(UWORD)InAdr);
  620.   }
  621.   InAdr=0;
  622.   if (ReadCode==-1)
  623.     return(-1);
  624.   return(0);
  625. }
  626.  
  627. void GetFlagsBuf()
  628. {
  629.   UWORD Flags,FlagsPlace,NewFlagsPlace;
  630.  
  631.   FlagsPlace=T->ECODE2[GetField() >> 6];
  632.   AddBit(T->NCODE2[FlagsPlace]);
  633.  
  634.   while (1)
  635.   {
  636.     Flags=D->ChSetC[FlagsPlace];
  637.     FlagBuf=(UBYTE)(Flags >> 8);
  638.     NewFlagsPlace=D->NToPlC[Flags++ & 0xff]++;
  639.     if ((Flags & 0xff) == 0)
  640.     {
  641.       Flags-=0x100;
  642.       CorrHuff(D->ChSetC,D->NToPlC);
  643.     }
  644.     else
  645.       break;
  646.   }
  647.  
  648.   D->ChSetC[FlagsPlace]=D->ChSetC[NewFlagsPlace];
  649.   D->ChSetC[NewFlagsPlace]=Flags;
  650. }
  651.  
  652.  
  653. void UnpInitData(Solid)
  654. int Solid;
  655. {
  656.   if (!Solid)
  657.   {
  658.     memset(D,0,sizeof(struct UnpData));
  659.     D->AvrPlc=0x3500;
  660.     D->MaxDist3=0x2001;
  661.     D->Nhfb=D->Nlzb=0x80;
  662.   }
  663.   FlagsCnt=0;
  664.   FlagBuf=0;
  665.   InAdr=0;
  666.   NumBit=0;
  667.   D->StMode=0;
  668.   LCount=0;
  669. }
  670.  
  671. void InitHuff()
  672. {
  673.   UWORD I;
  674.   for (I=0;I<256;I++)
  675.   {
  676.     D->Place[I]=D->PlaceA[I]=D->PlaceB[I]=(UBYTE)I;
  677.     D->PlaceC[I]=(UBYTE)(~I+1);
  678.     D->ChSet[I]=D->ChSetB[I]=I<<8;
  679.     D->ChSetA[I]=(UBYTE)I;
  680.     D->ChSetC[I]=(~I+1)<<8;
  681.   }
  682.   memset(D->NToPl,0,sizeof(D->NToPl));
  683.   memset(D->NToPlB,0,sizeof(D->NToPlB));
  684.   memset(D->NToPlC,0,sizeof(D->NToPlC));
  685.   CorrHuff(D->ChSetB,D->NToPlB);
  686. }
  687.  
  688.  
  689. void CorrHuff(CharSet,NumToPlace)
  690. UWORD *CharSet;
  691. UBYTE *NumToPlace;
  692. {
  693.   int I,J;
  694.   for (I=7;I>=0;I--)
  695.     for (J=0;J<32;J++,CharSet++)
  696.       *CharSet=(*CharSet & ~0xff) | I;
  697.   memset(NumToPlace,0,sizeof(D->NToPl));
  698.   for (I=6;I>=0;I--)
  699.     NumToPlace[I]=(7-I)*32;
  700. }
  701.  
  702. void CreateEncTbl(UnpMem)
  703. HPBYTE UnpMem;
  704. {
  705.   T=(struct DecodeTables *)(UnpMem+0x10000L+sizeof(struct UnpData));
  706.   CreateOneTbl(hcdsh1,T->ECDSH1,T->NCDSH1,8);
  707.   CreateOneTbl(hcdsh2,T->ECDSH2,T->NCDSH2,8);
  708.   CreateOneTbl(hcdsh3,T->ECDSH3,T->NCDSH3,8);
  709.   CreateOneTbl(hcdsh4,T->ECDSH4,T->NCDSH4,8);
  710.   CreateOneTbl(hcdln0,T->ECDLN0,T->NCDLN0,8);
  711.   CreateOneTbl(hcdln1,T->ECDLN1,T->NCDLN1,4);
  712.   CreateOneTbl(hcdln2,T->ECDLN2,T->NCDLN2,4);
  713.   CreateOneTbl(hcode0,T->ECODE0,T->NCODE0,4);
  714.   CreateOneTbl(hcode1,T->ECODE1,T->NCODE1,4);
  715.   CreateOneTbl(hcode2,T->ECODE2,T->NCODE2,6);
  716.   CreateOneTbl(hcode3,T->ECODE3,T->NCODE3,6);
  717.   CreateOneTbl(hcode4,T->ECODE4,T->NCODE4,6);
  718. }
  719.  
  720.  
  721. void CreateOneTbl(hcd,ecd,ncd,ShiftCount)
  722. UWORD *hcd;
  723. UBYTE *ecd;
  724. UBYTE *ncd;
  725. UBYTE ShiftCount;
  726. {
  727.   UWORD I,MaxCode,Code;
  728.   for (I=0; hcd[I]; I++)
  729.   {
  730.     ncd[I]=(UBYTE)(hcd[I] & 0xf);
  731.     Code=hcd[I] >> ShiftCount;
  732.     MaxCode=1 << (16-ShiftCount-(UBYTE)(hcd[I] & 0xf));
  733.     while (MaxCode--)
  734.       ecd[Code++]=(UBYTE)I;
  735.   }
  736. }
  737.  
  738.  
  739. void MakeTbl()
  740. {
  741.   UWORD I,J,K,Code;
  742.   UWORD *OutTab;
  743.   for (I=0;I<sizeof(MakeTab)/sizeof(MakeTab[0]);I++)
  744.   {
  745.     OutTab=MakeTab[I].Table;
  746.     for (Code=J=0;J<12;J++)
  747.       for (Code<<=1,K=0;K<MakeTab[I].HuffCodeCount[J];K++)
  748.         *(OutTab++)=(Code++ << (4+11-J)) | (J + 1);
  749.     *OutTab=0;
  750.   }
  751. }
  752.  
  753.