home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Amiga / Workbench / Archivers / ppunpackPPC.lha / PPUnpack / depack.c next >
C/C++ Source or Header  |  1998-02-25  |  2KB  |  117 lines

  1. /* depack.c */
  2.  
  3. /* copyright (c) Marc Espie, 1995 
  4.  * see accompanying file README for distribution information
  5.  */
  6.  
  7. #include "depack.h"
  8.  
  9. #define val(p) ((p)[0]<<16 | (p)[1] << 8 | (p)[2])
  10.  
  11.  
  12. ulong  depackedlen(packed, plen)
  13. ubyte *packed;
  14. ulong plen;
  15.    {
  16.     if (packed[0] != 'P' || packed[1] != 'P' || 
  17.         packed[2] != '2' || packed[3] != '0')
  18.             return 0; /* not a powerpacker file */
  19.     return val(packed+plen-4);
  20.    }
  21.  
  22. static ulong shift_in;
  23. static ulong counter = 0;
  24. static ubyte *source;
  25.  
  26. static ulong get_bits(ulong n)
  27.     {
  28.     ulong result = 0;
  29.     int i;
  30.  
  31.     for (i = 0; i < n; i++)
  32.         {
  33.         if (counter == 0)
  34.             {
  35.             counter = 8;
  36.             shift_in = *--source;
  37.             }
  38.         result = (result<<1) | (shift_in & 1);
  39.         shift_in >>= 1;
  40.         counter--;
  41.         }
  42.     return result;
  43.     }
  44.  
  45. void ppdepack(packed, depacked, plen, unplen)
  46. ubyte *packed, *depacked;
  47. ulong plen, unplen;
  48.    {
  49.     ubyte *dest;
  50.     int n_bits;
  51.     int idx;
  52.     ulong bytes;
  53.     int to_add;
  54.     ulong offset;
  55.    ubyte offset_sizes[4];
  56.     int i;
  57.    
  58.     offset_sizes[0] = packed[4];    /* skip signature */
  59.     offset_sizes[1] = packed[5];
  60.     offset_sizes[2] = packed[6];
  61.     offset_sizes[3] = packed[7];    
  62.  
  63.         /* initialize source of bits */
  64.     source = packed + plen - 4;
  65.  
  66.     dest = depacked + unplen;
  67.  
  68.         /* skip bits */
  69.     get_bits(source[3]);
  70.  
  71.         /* do it forever, i.e., while the whole file isn't unpacked */
  72.     while (1)
  73.         {
  74.             /* copy some bytes from the source anyway */
  75.         if (get_bits(1) == 0)
  76.             {
  77.             bytes = 0;
  78.             do {
  79.                 to_add = get_bits(2);
  80.                 bytes += to_add;
  81.                 } while (to_add == 3);
  82.             for (i = 0; i <= bytes; i++)
  83.                 *--dest = get_bits(8);
  84.             if (dest <= depacked)
  85.                 return;
  86.             }
  87.             /* decode what to copy from the destination file */
  88.         idx = get_bits(2);
  89.         n_bits = offset_sizes[idx];
  90.             /* bytes to copy */
  91.         bytes = idx+1;
  92.         if (bytes == 4)    /* 4 means >=4 */
  93.             {
  94.                 /* and maybe a bigger offset */
  95.             if (get_bits(1) == 0)
  96.                 offset = get_bits(7);
  97.             else
  98.                 offset = get_bits(n_bits);
  99.  
  100.             do {
  101.                 to_add = get_bits(3);
  102.                 bytes += to_add;
  103.                 } while (to_add == 7);
  104.             }
  105.         else
  106.             offset = get_bits(n_bits);
  107.         for (i = 0; i <= bytes; i++)
  108.             {
  109.             dest[-1] = dest[offset];
  110.             dest--;
  111.             }
  112.         if (dest <= depacked)
  113.             return;
  114.         }
  115.     }
  116.  
  117.