unreduce.c
上传用户:andy_li
上传日期:2007-01-06
资源大小:1019k
文件大小:6k
源码类别:

压缩解压

开发平台:

MultiPlatform

  1. /*---------------------------------------------------------------------------
  2.   unreduce.c
  3.   The Reducing algorithm is actually a combination of two distinct algorithms.
  4.   The first algorithm compresses repeated byte sequences, and the second al-
  5.   gorithm takes the compressed stream from the first algorithm and applies a
  6.   probabilistic compression method.
  7.      * Copyright 1989 Samuel H. Smith;  All rights reserved
  8.      *
  9.      * Do not distribute modified versions without my permission.
  10.      * Do not remove or alter this notice or any other copyright notice.
  11.      * If you use this in your own program you must distribute source code.
  12.      * Do not use any of this in a commercial product.
  13.   See the accompanying file "COPYING" in UnZip source and binary distributions
  14.   for further information.  This code is NOT used unless USE_SMITH_CODE is
  15.   explicitly defined (==> COPYRIGHT_CLEAN is not defined).
  16.   ---------------------------------------------------------------------------*/
  17. #define UNZIP_INTERNAL
  18. #include "unzip.h"   /* defines COPYRIGHT_CLEAN by default */
  19. #ifndef COPYRIGHT_CLEAN
  20. /**************************************/
  21. /*  UnReduce Defines, Typedefs, etc.  */
  22. /**************************************/
  23. #define DLE    144
  24. typedef uch f_array[64];        /* for followers[256][64] */
  25. /******************************/
  26. /*  UnReduce Local Functions  */
  27. /******************************/
  28. static void LoadFollowers OF((__GPRO__ f_array *followers, uch *Slen));
  29. /*******************************/
  30. /*  UnReduce Global Constants  */
  31. /*******************************/
  32. static ZCONST shrint L_table[] =
  33. {0, 0x7f, 0x3f, 0x1f, 0x0f};
  34. static ZCONST shrint D_shift[] =
  35. {0, 0x07, 0x06, 0x05, 0x04};
  36. static ZCONST shrint D_mask[] =
  37. {0, 0x01, 0x03, 0x07, 0x0f};
  38. static ZCONST shrint B_table[] =
  39. {8, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5,
  40.  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
  41.  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  42.  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
  43.  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  44.  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  45.  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  46.  7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  47.  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  48.  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  49.  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  50.  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  51.  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  52.  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  53.  8, 8, 8, 8};
  54. /*************************/
  55. /*  Function unreduce()  */
  56. /*************************/
  57. void unreduce(__G)   /* expand probabilistically reduced data */
  58.      __GDEF
  59. {
  60.     register int lchar = 0;
  61.     shrint nchar;
  62.     shrint ExState = 0;
  63.     shrint V = 0;
  64.     shrint Len = 0;
  65.     long s = G.ucsize;  /* number of bytes left to decompress */
  66.     unsigned w = 0;      /* position in output window slide[] */
  67.     unsigned u = 1;      /* true if slide[] unflushed */
  68.     uch Slen[256];
  69.     f_array *followers = (f_array *)(slide + 0x4000);
  70.     int factor = G.lrec.compression_method - 1;
  71.     LoadFollowers(__G__ followers, Slen);
  72.     while (s > 0 /* && (!zipeof) */) {
  73.         if (Slen[lchar] == 0)
  74.             READBITS(8, nchar)   /* ; */
  75.         else {
  76.             READBITS(1, nchar)   /* ; */
  77.             if (nchar != 0)
  78.                 READBITS(8, nchar)       /* ; */
  79.             else {
  80.                 shrint follower;
  81.                 int bitsneeded = B_table[Slen[lchar]];
  82.                 READBITS(bitsneeded, follower)   /* ; */
  83.                 nchar = followers[lchar][follower];
  84.             }
  85.         }
  86.         /* expand the resulting byte */
  87.         switch (ExState) {
  88.         case 0:
  89.             if (nchar != DLE) {
  90.                 s--;
  91.                 slide[w++] = (uch)nchar;
  92.                 if (w == 0x4000) {
  93.                     flush(__G__ slide, (ulg)w, 0);
  94.                     w = u = 0;
  95.                 }
  96.             }
  97.             else
  98.                 ExState = 1;
  99.             break;
  100.         case 1:
  101.             if (nchar != 0) {
  102.                 V = nchar;
  103.                 Len = V & L_table[factor];
  104.                 if (Len == L_table[factor])
  105.                     ExState = 2;
  106.                 else
  107.                     ExState = 3;
  108.             } else {
  109.                 s--;
  110.                 slide[w++] = DLE;
  111.                 if (w == 0x4000)
  112.                 {
  113.                   flush(__G__ slide, (ulg)w, 0);
  114.                   w = u = 0;
  115.                 }
  116.                 ExState = 0;
  117.             }
  118.             break;
  119.         case 2:{
  120.                 Len += nchar;
  121.                 ExState = 3;
  122.             }
  123.             break;
  124.         case 3:{
  125.                 register unsigned e;
  126.                 register unsigned n = Len + 3;
  127.                 register unsigned d = w - ((((V >> D_shift[factor]) &
  128.                                D_mask[factor]) << 8) + nchar + 1);
  129.                 s -= n;
  130.                 do {
  131.                   n -= (e = (e = 0x4000 - ((d &= 0x3fff) > w ? d : w)) > n ?
  132.                         n : e);
  133.                   if (u && w <= d)
  134.                   {
  135.                     memzero(slide + w, e);
  136.                     w += e;
  137.                     d += e;
  138.                   }
  139.                   else
  140.                     if (w - d < e)      /* (assume unsigned comparison) */
  141.                       do {              /* slow to avoid memcpy() overlap */
  142.                         slide[w++] = slide[d++];
  143.                       } while (--e);
  144.                     else
  145.                     {
  146.                       memcpy(slide + w, slide + d, e);
  147.                       w += e;
  148.                       d += e;
  149.                     }
  150.                   if (w == 0x4000)
  151.                   {
  152.                     flush(__G__ slide, (ulg)w, 0);
  153.                     w = u = 0;
  154.                   }
  155.                 } while (n);
  156.                 ExState = 0;
  157.             }
  158.             break;
  159.         }
  160.         /* store character for next iteration */
  161.         lchar = nchar;
  162.     }
  163.     /* flush out slide */
  164.     flush(__G__ slide, (ulg)w, 0);
  165. }
  166. /******************************/
  167. /*  Function LoadFollowers()  */
  168. /******************************/
  169. static void LoadFollowers(__G__ followers, Slen)
  170.      __GDEF
  171.      f_array *followers;
  172.      uch *Slen;
  173. {
  174.     register int x;
  175.     register int i;
  176.     for (x = 255; x >= 0; x--) {
  177.         READBITS(6, Slen[x])   /* ; */
  178.         for (i = 0; (uch)i < Slen[x]; i++)
  179.             READBITS(8, followers[x][i])   /* ; */
  180.     }
  181. }
  182. #endif /* !COPYRIGHT_CLEAN */