home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Amiga / Workbench / Archivers / PPUnpackWOS.lha / depack.c next >
C/C++ Source or Header  |  1998-03-02  |  3KB  |  113 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(ubyte *packed, ulong plen)
  13.    {
  14.         if (packed[0] != 'P' || packed[1] != 'P' || 
  15.                 packed[2] != '2' || packed[3] != '0')
  16.                         return 0; /* not a powerpacker file */
  17.         return val(packed+plen-4);
  18.    }
  19.  
  20. static ulong shift_in;
  21. static ulong counter = 0;
  22. static ubyte *source;
  23.  
  24. static ulong get_bits(ulong n)
  25.         {
  26.         ulong result = 0;
  27.         int i;
  28.  
  29.         for (i = 0; i < n; i++)
  30.                 {
  31.                 if (counter == 0)
  32.                         {
  33.                         counter = 8;
  34.                         shift_in = *--source;
  35.                         }
  36.                 result = (result<<1) | (shift_in & 1);
  37.                 shift_in >>= 1;
  38.                 counter--;
  39.                 }
  40.         return result;
  41.         }
  42.  
  43. void ppdepack(ubyte *packed, ubyte *depacked, ulong plen, ulong unplen)
  44.    {
  45.         ubyte *dest;
  46.         int n_bits;
  47.         int idx;
  48.         ulong bytes;
  49.         int to_add;
  50.         ulong offset;
  51.    ubyte offset_sizes[4];
  52.         int i;
  53.    
  54.         offset_sizes[0] = packed[4];    /* skip signature */
  55.         offset_sizes[1] = packed[5];
  56.         offset_sizes[2] = packed[6];
  57.         offset_sizes[3] = packed[7];    
  58.  
  59.                 /* initialize source of bits */
  60.         source = packed + plen - 4;
  61.  
  62.         dest = depacked + unplen;
  63.  
  64.                 /* skip bits */
  65.         get_bits(source[3]);
  66.  
  67.                 /* do it forever, i.e., while the whole file isn't unpacked */
  68.         while (1)
  69.                 {
  70.                         /* copy some bytes from the source anyway */
  71.                 if (get_bits(1) == 0)
  72.                         {
  73.                         bytes = 0;
  74.                         do {
  75.                                 to_add = get_bits(2);
  76.                                 bytes += to_add;
  77.                                 } while (to_add == 3);
  78.                         for (i = 0; i <= bytes; i++)
  79.                                 *--dest = get_bits(8);
  80.                         if (dest <= depacked)
  81.                                 return;
  82.                         }
  83.                         /* decode what to copy from the destination file */
  84.                 idx = get_bits(2);
  85.                 n_bits = offset_sizes[idx];
  86.                         /* bytes to copy */
  87.                 bytes = idx+1;
  88.                 if (bytes == 4) /* 4 means >=4 */
  89.                         {
  90.                                 /* and maybe a bigger offset */
  91.                         if (get_bits(1) == 0)
  92.                                 offset = get_bits(7);
  93.                         else
  94.                                 offset = get_bits(n_bits);
  95.  
  96.                         do {
  97.                                 to_add = get_bits(3);
  98.                                 bytes += to_add;
  99.                                 } while (to_add == 7);
  100.                         }
  101.                 else
  102.                         offset = get_bits(n_bits);
  103.                 for (i = 0; i <= bytes; i++)
  104.                         {
  105.                         dest[-1] = dest[offset];
  106.                         dest--;
  107.                         }
  108.                 if (dest <= depacked)
  109.                         return;
  110.                 }
  111.         }
  112.  
  113.