jjj1deco.c
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:12k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. /*
  2. **  JJJ1DECO.C  --  Jeff Johnson Decompression module - first implementation
  3. */
  4. /*  This code was written by modifying the Zeck compression code
  5. **  and adding a triple huffman compressor.  The results are much
  6. **  smaller.  This was done by Jeff Johnson, 10/15/90 to accomodate
  7. **  Microsoft Excel 3.0.
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include <io.h>
  14. #include <fcntl.h>
  15. #include "..sutkcomp.h"
  16. #ifdef OS2SU
  17. #include <doscalls.h>
  18. #endif
  19. #include "jjj1.h"
  20. #include "setjmp.h"
  21. extern BOOL vfUserCancel;
  22. extern PFNWFROMW vpfnYield;
  23. extern BOOL    fJmpEnvSet;
  24. extern jmp_buf jmpEnv;
  25.   /* forward declarations */
  26. BOOL  UnpackJJJ1(void);
  27. /*
  28. **  LONG  Lcb_JJJ1_DecompressToFile(int fhSrc, int fhDest, LONG lcbDestMax,
  29. **              LONG libStart, BYTE far * fpbBuf, LONG lcbBuf)
  30. */
  31. LONG Lcb_JJJ1_DecompressToFile(int fhSrc, int fhDest, LONG lcbDestMax,
  32.            LONG libStart, BYTE far * fpbBuf, LONG lcbBuf)
  33. {
  34.     int iJmpReturn;
  35.     if (lcbDestMax != NIL)
  36.         return((LONG)rcGenericDecompError);
  37.     if (!FAllocateJJJGlobals((lcbDestMax == NIL) ? NIL : (libStart +lcbDestMax),
  38.                                                                          FALSE))
  39.         return((LONG)rcOutOfMemory);
  40.     if ((iJmpReturn = setjmp(jmpEnv)) != 0)
  41.         {
  42.         fJmpEnvSet = FALSE;
  43.         FreeJJJGlobals();
  44.         return((LONG)iJmpReturn);
  45.         }
  46.     fJmpEnvSet = TRUE;
  47.       /* lcbDestStop == libStart + lcbDestMax */
  48.     if (lcbDestMax != NIL && (LONG)(fpbOutBufEnd - fpbOutBuf) > lcbDestStop)
  49.         fpbOutBufEnd = fpbOutBuf + (SHORT)lcbDestStop;
  50.     fhDestGlobal = fhDest;
  51.     fhSrcGlobal = fhSrc;
  52.     lcbSkipOut = libStart;
  53.     fpbBufDest = NULL;
  54.     if (!UnpackJJJ1())
  55.         {
  56.         fJmpEnvSet = FALSE;
  57.         FreeJJJGlobals();
  58.         return((LONG)rcGenericDecompError);
  59.         }
  60.     fJmpEnvSet = FALSE;
  61.     FreeJJJGlobals();
  62.     if (fWriteError)
  63.         return((LONG)rcWriteError);
  64.     else
  65.         return(lcbDest - libStart);
  66. }
  67. #ifdef COMPLEX
  68. /*
  69. **  LONG Lcb_JJJ1_DecompressToBuffer(int fhSrc, BYTE far * fpbBuf, LONG lcbBuf,
  70. **                                                               LONG libStart)
  71. */
  72. LONG Lcb_JJJ1_DecompressToBuffer(int fhSrc, BYTE far * fpbBuf, LONG lcbBuf,
  73.                                                                  LONG libStart)
  74. {
  75.     int iJmpReturn;
  76.     if (lcbBuf <= 0L)
  77.         return((LONG)rcGenericDecompError);
  78.     if (!FAllocateJJJGlobals(libStart + lcbBuf, FALSE))
  79.         return((LONG)rcOutOfMemory);
  80.     if ((iJmpReturn = setjmp(jmpEnv)) != 0)
  81.         {
  82.         fJmpEnvSet = FALSE;
  83.         fpbBufDest = NULL;
  84.         FreeJJJGlobals();
  85.         return((LONG)iJmpReturn);
  86.         }
  87.     fJmpEnvSet = TRUE;
  88.       /* lcbDestStop == libStart + lcbBuf */
  89.     if ((LONG)(fpbOutBufEnd - fpbOutBuf) > lcbDestStop)
  90.         fpbOutBufEnd = fpbOutBuf + (SHORT)lcbDestStop;
  91.     lcbSkipOut = libStart;
  92.     fpbBufDest = fpbBuf;
  93.     fhDestGlobal = -1;
  94.     fhSrcGlobal = fhSrc;
  95.     if (!UnpackJJJ1())
  96.         {
  97.         fJmpEnvSet = FALSE;
  98.         fpbBufDest = NULL;
  99.         FreeJJJGlobals();
  100.         return((LONG)rcGenericDecompError);
  101.         }
  102.     fJmpEnvSet = FALSE;
  103.     fpbBufDest = NULL;
  104.     FreeJJJGlobals();
  105.     if (fWriteError)
  106.         return((LONG)rcWriteError);
  107.     else
  108.         return(lcbDest - libStart);
  109. }
  110. #endif /* COMPLEX */
  111. USHORT  usIHold = 0, cbIHold = 0;
  112. BOOL    fHitEOF = FALSE;
  113. int  ReadHuffman(CODETABLE far *fpct, BYTE far *fpbLookup)
  114. {
  115.     USHORT  b, ndx, ent;
  116.     if (cbIHold < 8)
  117.         {
  118.         if (!fHitEOF)
  119.             {
  120.             if ((b = ReadByte(fhSrcGlobal)) == EOF)
  121.                 {
  122.                 fHitEOF = (BOOL)TRUE;
  123.                 ent = fpbLookup[((usIHold << (8 - cbIHold)) & 255)];
  124.                 if (cbIHold >= fpct[ent].cbCode)
  125.                     {
  126.                     cbIHold -= fpct[ent].cbCode;
  127.                     return(ent);
  128.                     }
  129.                 return(EOF);
  130.                 }
  131.             usIHold = (usIHold << 8) | b;
  132.             cbIHold += 8;
  133.             }
  134.         else
  135.             {
  136.             ent = fpbLookup[((usIHold << (8 - cbIHold)) & 255)];
  137.             if (cbIHold >= fpct[ent].cbCode)
  138.                 {
  139.                 cbIHold -= fpct[ent].cbCode;
  140.                 return(ent);
  141.                 }
  142.             return(EOF);
  143.             }
  144.         }
  145.     ndx = usIHold >> (cbIHold - 8);
  146.     ent = fpbLookup[ndx & 255];
  147.     if (fpct[ent].cbCode <= 8)
  148.         {
  149.         cbIHold -= fpct[ent].cbCode;
  150.         return(ent);
  151.         }
  152.     // We have to walk the linked list
  153.     cbIHold -= 8;
  154.     if ((b = ReadByte(fhSrcGlobal)) == EOF)
  155.         fHitEOF = (BOOL)TRUE;
  156.     else
  157.         {
  158.         usIHold = (usIHold << 8) | b;
  159.         cbIHold += 8;
  160.         }
  161.     while(1)
  162.         {
  163.         if (cbIHold + 8 < fpct[ent].cbCode)
  164.             return(EOF);
  165.         ndx = fpct[ent].cbCode - 8;
  166.         if (((usIHold >> (cbIHold - ndx)) & iPowers[ndx]) ==
  167.                 (fpct[ent].usCode&iPowers[ndx]))
  168.             {
  169.             cbIHold -= ndx;
  170.             return(ent);
  171.             }
  172.         ent = fpct[ent].nextCode;
  173.         }
  174. }
  175. int  ReadBits(int bitcnt)
  176. {
  177.     int  b;
  178.     if ((int) cbIHold < bitcnt)
  179.         if (!fHitEOF)
  180.             {
  181.             if ((b = ReadByte(fhSrcGlobal)) == EOF)
  182.                 {
  183.                 fHitEOF = (BOOL)TRUE;
  184.                 return(EOF);
  185.                 }
  186.             usIHold = (usIHold<<8) | b;
  187.             cbIHold += 8;
  188.             }
  189.         else
  190.             return(EOF);
  191.     cbIHold -= bitcnt;
  192.     return((usIHold >> cbIHold) & iPowers[bitcnt]);
  193. }
  194. void  ReadHTable(CODETABLE far *fpct, int usct, int Method)
  195. {
  196.     int   cnt, b;
  197.     BYTE  byte;
  198.     switch (Method)
  199.         {
  200.     case NOTABLE: // Build an evensized huffman table
  201.         b = 0;
  202.         cnt = usct;
  203.         while (cnt >>= 1)
  204.             b++;
  205.         for (cnt = 0; cnt < usct; cnt++)
  206.             fpct[cnt].cbCode = (BYTE) b;
  207.         break;
  208.     case COMPRESSNONE:
  209.         for (cnt = 0; cnt < usct; cnt += 2)
  210.             {
  211.             b = ReadBits(8);
  212.             fpct[cnt  ].cbCode = (BYTE) ((int) b>>4);
  213.             fpct[cnt+1].cbCode = (BYTE) ((int) b&15);
  214.             }
  215.         break;
  216.     case COMPRESS1BIT:
  217.         fpct[0].cbCode = byte = (BYTE) ReadBits(4);
  218.         for (cnt = 1; cnt < usct; cnt++)
  219.             {
  220.             if (!ReadBits(1))
  221.                 fpct[cnt].cbCode = byte;
  222.             else if (!ReadBits(1))
  223.                 fpct[cnt].cbCode = ++byte;
  224.             else
  225.                 fpct[cnt].cbCode = byte = (BYTE) ReadBits(4);
  226.             }
  227.         break;
  228.     case COMPRESS2BIT:
  229.         fpct[0].cbCode = byte = (BYTE) ReadBits(4);
  230.         for (cnt = 1; cnt < usct; cnt++)
  231.             {
  232.             if ((b=ReadBits(2)) != 3)
  233.                 fpct[cnt].cbCode = byte += (b-1);
  234.             else
  235.                 fpct[cnt].cbCode = byte = (BYTE) ReadBits(4);
  236.             }
  237.         break;
  238.         }
  239. }
  240. void  BuildHLookup(CODETABLE far *fpct, BYTE far *fpbLookup, int usct)
  241. {
  242.     int  usLookup = 0, cnt = 0, bCurNdx;
  243.     int  bCurCode = 0, bCurLen = 100;
  244.     int  iTemp; // HACK!!! bug in C600x requires expr to be broken down!
  245.                 // Otherwise it uses a WORD PTR instead of a BYTE PTR and
  246.                 // this GP faults as the 2nd byte often hangs off the edge
  247.                 // of a segment!!!
  248.     for (cnt = 0; cnt < usct; cnt++)
  249.         {
  250.         if ((fpct[cnt].cbCode < (BYTE)bCurLen) && fpct[cnt].cbCode)
  251.             {
  252.             bCurLen = fpct[cnt].cbCode;
  253.             bCurNdx = cnt;
  254.             }
  255.         }
  256.     bCurCode = fpct[bCurNdx].usCode;
  257.     if (bCurLen > 8)
  258.         {
  259.         bCurCode >>= (bCurLen - 8);
  260.         bCurLen    = 8;
  261.         }
  262.     cnt = 0;
  263.     while (1)
  264.         {
  265.         while (((cnt>>(8-bCurLen)) == bCurCode) && cnt < 256)
  266.             fpbLookup[cnt++] = (BYTE) bCurNdx;
  267.         iTemp = fpct[bCurNdx].nextCode;
  268.         if (cnt == 256)
  269.             break;
  270.         if (fpct[iTemp].cbCode <= 8)
  271.             bCurNdx = fpct[bCurNdx].nextCode;
  272.         else
  273.             {
  274.             while (1)
  275.                 {
  276.                 bCurNdx = fpct[bCurNdx].nextCode;
  277.                 if ((fpct[bCurNdx].usCode>>(fpct[bCurNdx].cbCode-8)) != 
  278.                         (BYTE) bCurCode)
  279.                     break;
  280.                 }
  281.             }
  282.         bCurCode= fpct[bCurNdx].usCode;
  283.         if ((bCurLen = fpct[bCurNdx].cbCode) > 8)
  284.             {
  285.             bCurCode >>= (bCurLen-8);
  286.             bCurLen  = 8;
  287.             }
  288.         }
  289. }
  290. /*
  291. **  BOOL UnpackJJJ1(void)
  292. */
  293. BOOL UnpackJJJ1(void)
  294. {
  295.     int     i, cb, oStart, ibBufCur;
  296.     USHORT  b, cnt, in;
  297.     USHORT  usFlags;
  298.     LONG    lcbOut;
  299.     int     cType;
  300.     int     b8Bit, b6Bit, b4aBit, b4bBit, b5Bit;
  301.     int     isPtr = FALSE;
  302.     USHORT  cCyclesUntilBreak = 1;
  303.     vfUserCancel = FALSE;
  304.     ibBufCur = cbBufMax - cbStrMax;
  305.     usFlags = 0;
  306.     lcbOut = 0;
  307.     // Get the code table compression info
  308.     b4aBit  = b4bBit = ReadByte(fhSrcGlobal);
  309.     b5Bit   = b6Bit  = ReadByte(fhSrcGlobal);
  310.     b8Bit            = ReadByte(fhSrcGlobal);
  311.     b4aBit >>= 4;
  312.     b5Bit  >>= 4;
  313.     b8Bit  >>= 4;
  314.     b4bBit &= 15;
  315.     b6Bit  &= 15;
  316.     _fmemset(ringBuf, ' ', cbBufMax - cbStrMax);
  317.     cbIHold = 0;      //Reset globals
  318.     fHitEOF = FALSE;
  319.     ReadHTable(fpct4a, 16, b4aBit);
  320.     BuildCodeTable(fpct4a, 16);
  321.     BuildHLookup(fpct4a, fpbLookup4a, 16);
  322.     ReadHTable(fpct4b, 16, b4bBit);
  323.     BuildCodeTable(fpct4b, 16);
  324.     BuildHLookup(fpct4b, fpbLookup4b, 16);
  325.     ReadHTable(fpct5, 32, b5Bit);
  326.     BuildCodeTable(fpct5, 32);
  327.     BuildHLookup(fpct5, fpbLookup5, 32);
  328.     ReadHTable(fpct6, 64, b6Bit);
  329.     BuildCodeTable(fpct6, 64); 
  330.     BuildHLookup(fpct6, fpbLookup6, 64);
  331.     ReadHTable(fpct8, 256, b8Bit);
  332.     BuildCodeTable(fpct8, 256);
  333.     BuildHLookup(fpct8, fpbLookup8, 256);
  334.     while (TRUE)
  335.         {
  336.         if (--cCyclesUntilBreak == 0)
  337.             {
  338.             if (vpfnYield != NULL)
  339.                 {
  340.                 cCyclesUntilBreak = 300;
  341.                 (*vpfnYield)(0);
  342.                 }
  343.             else
  344.                 cCyclesUntilBreak = 30000;
  345.             if (vfUserCancel)
  346.                 {
  347.                 if (fJmpEnvSet)
  348.                     longjmp(jmpEnv, rcGenericDecompError);
  349.                 else
  350.                     return((BOOL)FALSE);
  351.                 }
  352.             }
  353.         if (isPtr)
  354.             {
  355.             if ((cType = ReadHuffman(fpct4b, fpbLookup4b)) == EOF)
  356.                 break;
  357.             }
  358.         else
  359.             {
  360.             if ((cType = ReadHuffman(fpct4a, fpbLookup4a)) == EOF)
  361.                break;
  362.             }
  363.         if (cType) // It's a pointer
  364.             {
  365.             isPtr = FALSE;
  366.             /* extract the buffer offset and count to unpack */
  367.             if ((oStart = ReadHuffman(fpct6, fpbLookup6)) == EOF)
  368.                 break;
  369.             if ((i = ReadBits(6)) == EOF)
  370.                 break;
  371.             oStart  = (oStart << 6) | i;
  372.             oStart  = (ibBufCur - oStart + cbBufMax) & (cbBufMax - 1);
  373.             cb = cType + cbIndex - 1;
  374.             for (i = 0; i <= cb; i++)
  375.                 {
  376.                 WriteByte((BYTE)(b = ringBuf[(oStart + i) & (cbBufMax - 1)]));
  377.                 if (fDestFull)
  378.                     return((BOOL)TRUE);
  379.                 lcbOut++;
  380.                 ringBuf[ibBufCur++] = (BYTE)b;
  381.                 ibBufCur &= cbBufMax - 1;
  382.                 }
  383.             }
  384.         else  // It's a literal count
  385.             {
  386.             if ((b = ReadHuffman(fpct5, fpbLookup5) + 1) == cbLitMax)
  387.                 isPtr = FALSE;
  388.             else
  389.                 isPtr = TRUE;
  390.             for (cnt = 0; cnt < b; cnt++)
  391.                 {
  392.                 if ((in = ReadHuffman(fpct8, fpbLookup8)) == EOF)
  393.                     break;
  394.                 WriteByte((BYTE)in);
  395.                 if (fDestFull)
  396.                     return((BOOL)TRUE);
  397.                 lcbOut++;
  398.                 ringBuf[ibBufCur++] = (BYTE)in;
  399.                 ibBufCur &= cbBufMax - 1;
  400.                 }
  401.             if (cnt != b)
  402.                 break;
  403.             }
  404.      } 
  405.      if (!eof(fhSrcGlobal))
  406.          return((BOOL)TRUE);  // not an error condition if splitting file
  407.      WriteOutBuff((BYTE)'');
  408.      return((BOOL)TRUE);
  409. }