uncompress.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:12k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* uncompress.c - uncompression module */
  2. /* Copyright 1990-1992 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 02h,04nov93,caf  fixed two more variables that were not being initialized
  8.  during the R3000 bootstrap.
  9. 02g,07sep93,caf  modified not to rely on initialized data, to work around
  10.  a.out assumption in current bootstrap.
  11. 02f,26may92,rrr  the tree shuffle
  12. 02e,14nov91,rrr  shut up some warnings
  13. 02d,04oct91,rrr  passed through the ansification filter
  14.                   -changed functions to ansi style
  15.   -fixed #else and #endif
  16.   -changed copyright notice
  17. 02c,25jul91,yao  restore previous version 02a.
  18. 02b,06jul91,yao  made it work with little endian mode. added forward
  19.  declaration.
  20. 02a,16may90,gae  revised initial bootrom uncompression scheme --
  21.            ROM startup in separate module.
  22. 01a,21apr90,rdc  modified from compress source.
  23. */
  24. /*
  25. DESCRIPTION
  26. This is a modified version of the Public Domain uncompress program.
  27. It is used to uncompress the VxWorks bootrom executable linked with it.
  28. Compressing object code typically achieves a 40% compression factor.
  29. SEE ALSO:
  30. compress(1), romInit(1)
  31. AUTHOR
  32. The original compress program was written by:
  33. Spencer W. Thomas, Jim McKie, Steve Davies, Ken Turkowski,
  34. James A. Woods, Joe Orost.
  35. */
  36. #include "vxWorks.h"
  37. /* Set USERMEM to the maximum amount of physical user memory available
  38.  * in bytes.  USERMEM is used to determine the maximum BITS that can be used
  39.  * for compression.  If USERMEM is big enough, use fast compression algorithm.
  40.  *
  41.  * SACREDMEM is the amount of physical memory saved for others; compress
  42.  * will hog the rest.
  43.  */
  44. #define USERMEM 500000 /* .5M for uncompression data structures */
  45. #define SACREDMEM 0
  46. /*
  47.  * Define FBITS for machines with several MB of physical memory, to use
  48.  * table lookup for (b <= FBITS).  If FBITS is made too large, performance
  49.  * will decrease due to increased swapping/paging.  Since the program minus
  50.  * the fast lookup table is about a half Meg, we can allocate the rest of
  51.  * available physical memory to the fast lookup table.
  52.  *
  53.  * If FBITS is set to 12, a 2 MB array is allocated, but only 1 MB is
  54.  * addressed for parity-free input (i.e. text).
  55.  *
  56.  * FBITS=10 yields 1/2 meg lookup table + 4K code memory
  57.  * FBITS=11 yields 1 meg lookup table + 8K code memory
  58.  * FBITS=12 yields 2 meg lookup table + 16K code memory
  59.  * FBITS=13 yields 4 meg lookup table + 32K code memory
  60.  *
  61.  */
  62. #ifdef USERMEM
  63. # if USERMEM >= (2621440+SACREDMEM)
  64. #  if USERMEM >= (4718592+SACREDMEM)
  65. #   define FBITS 13
  66. #   define PBITS 16
  67. #else /* 2.5M <= USERMEM < 4.5M */
  68. #   define FBITS 12
  69. #   define PBITS 16
  70. #endif /* USERMEM <=> 4.5M */
  71. #else /* USERMEM < 2.5M */
  72. #  if USERMEM >= (1572864+SACREDMEM)
  73. #   define FBITS 11
  74. #   define PBITS 16
  75. #else /* USERMEM < 1.5M */
  76. #   if USERMEM >= (1048576+SACREDMEM)
  77. #    define FBITS 10
  78. #    define PBITS 16
  79. #else /* USERMEM < 1M */
  80. #    if USERMEM >= (631808+SACREDMEM)
  81. #     define PBITS 16
  82. #    else
  83. #     if USERMEM >= (329728+SACREDMEM)
  84. #      define PBITS 15
  85. #     else
  86. #      if USERMEM >= (178176+SACREDMEM)
  87. #       define PBITS 14
  88. #      else
  89. #       if USERMEM >= (99328+SACREDMEM)
  90. #        define PBITS 13
  91. #       else
  92. #        define PBITS 12
  93. #       endif
  94. #      endif
  95. #     endif
  96. #    endif
  97. #    undef USERMEM
  98. #endif /* USERMEM <=> 1M */
  99. #endif /* USERMEM <=> 1.5M */
  100. #endif /* USERMEM <=> 2.5M */
  101. #endif /* USERMEM */
  102. #ifdef PBITS /* Preferred BITS for this memory size */
  103. # ifndef BITS
  104. #  define BITS PBITS
  105. #endif /* BITS */
  106. #endif /* PBITS */
  107. #if BITS == 16
  108. # define HSIZE 69001 /* 95% occupancy */
  109. #endif /* BITS */
  110. #if BITS == 15
  111. # define HSIZE 35023 /* 94% occupancy */
  112. #endif /* BITS */
  113. #if BITS == 14
  114. # define HSIZE 18013 /* 91% occupancy */
  115. #endif /* BITS */
  116. #if BITS == 13
  117. # define HSIZE 9001 /* 91% occupancy */
  118. #endif /* BITS */
  119. #if BITS == 12
  120. # define HSIZE 5003 /* 80% occupancy */
  121. #endif /* BITS */
  122. #if BITS == 11
  123. # define HSIZE 2591 /* 79% occupancy */
  124. #endif /* BITS */
  125. #if BITS == 10
  126. # define HSIZE 1291 /* 79% occupancy */
  127. #endif /* BITS */
  128. #if BITS == 9
  129. # define HSIZE 691 /* 74% occupancy */
  130. #endif /* BITS */
  131. /* BITS < 9 will cause an error */
  132. /*
  133.  * a code_int must be able to hold 2**BITS values of type int, and also -1
  134.  */
  135. #if BITS > 15
  136. typedef long int code_int;
  137. #else
  138. typedef int     code_int;
  139. #endif /* BITS */
  140. typedef long int count_int;
  141. typedef unsigned char char_type;
  142. /* defines for magic number {"37235"} */
  143. #define MAGIC_HEADER_0 0x1f
  144. #define MAGIC_HEADER_1 0x9d
  145. /* Defines for third byte of header */
  146. #define BIT_MASK 0x1f
  147. #define BLOCK_MASK 0x80
  148. /* Masks 0x40 and 0x20 are free.  I think 0x20 should mean that there is
  149.    a fourth header byte (for expansion).
  150. */
  151. #define INIT_BITS 9 /* initial number of bits/code */
  152. LOCAL int             n_bits; /* number of bits/code */
  153. LOCAL int             maxbits;
  154. LOCAL code_int        maxcode; /* maximum code, given n_bits */
  155. LOCAL code_int        maxmaxcode; /* should NEVER generate this code */
  156. #define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
  157. /*
  158.  * One code could conceivably represent (1<<BITS) characters, but
  159.  * to get a code of length N requires an input string of at least
  160.  * N*(N-1)/2 characters.  With 5000 chars in the stack, an input
  161.  * file would have to contain a 25Mb string of a single character.
  162.  * This seems unlikely.
  163.  */
  164. #define MAXSTACK    8000 /* size of output stack */
  165. LOCAL unsigned short  codetab[HSIZE];
  166. LOCAL code_int        hsize; /* for dynamic table sizing */
  167. LOCAL count_int       fsize;
  168. #define tab_prefix codetab /* prefix code for this entry */
  169. LOCAL char_type       tab_suffix[1 << BITS]; /* last char in this entry */
  170. LOCAL code_int        free_ent; /* first unused entry */
  171. #define NOMAGIC 0 /* use 2 byte magic number header, unless old file */
  172. /*
  173.  * block compression parameters -- after all codes are used up,
  174.  * and compression rate changes, start over.
  175.  */
  176. LOCAL int block_compress;
  177. LOCAL int clear_flg;
  178. LOCAL char_type rmask[9]; /* initialize in uncompress() */
  179. /* The next two codes should not be changed lightly, as they must not
  180.  * lie within the contiguous general code space.
  181.  */
  182. #define FIRST 257 /* first free entry */
  183. #define CLEAR 256 /* table clear output code */
  184. LOCAL UCHAR *binEnd;
  185. LOCAL UCHAR *binArray;
  186. LOCAL int offset; /* zero'd by uncompress(), used by getcode() */
  187. LOCAL int size; /* zero'd by uncompress(), used by getcode() */
  188. /* forward static functions */
  189. static code_int getcode (void);
  190. /*******************************************************************************
  191. *
  192. * uncompress - uncompress `source' to `destination'
  193. *
  194. * This routine uncompresses the image found at `source' to the `destination'
  195. * address, where the source is `len' bytes long.
  196. */
  197. STATUS uncompress
  198.     (
  199.     UCHAR *source,              /* start of compressed image */
  200.     FAST UCHAR *destination,    /* destination for uncompressed result */
  201.     int len                     /* length of compressed image */
  202.     )
  203.     {
  204.     static char stack [MAXSTACK];
  205.     FAST int stack_top = MAXSTACK;
  206.     FAST code_int code;
  207.     FAST code_int oldcode;
  208.     FAST code_int incode;
  209.     FAST int finchar;
  210.     binEnd = &source [len];
  211.     binArray = source;
  212.     /* initialize */
  213.     offset = 0; /* used by getcode() */
  214.     size = 0; /* used by getcode() */
  215.     block_compress  = BLOCK_MASK;
  216.     fsize           = 200000;
  217.     clear_flg       = 0;
  218.     maxbits        = BITS;
  219.     if (maxbits < INIT_BITS)
  220. maxbits = INIT_BITS;
  221.     if (maxbits > BITS)
  222. maxbits = BITS;
  223.     maxmaxcode = 1 << maxbits;
  224.     rmask[0] = 0x00;
  225.     rmask[1] = 0x01;
  226.     rmask[2] = 0x03;
  227.     rmask[3] = 0x07;
  228.     rmask[4] = 0x0f;
  229.     rmask[5] = 0x1f;
  230.     rmask[6] = 0x3f;
  231.     rmask[7] = 0x7f;
  232.     rmask[8] = 0xff;
  233.     /* check the magic number */
  234.     if (NOMAGIC == 0)
  235.         {
  236. if ((*binArray++) != (MAGIC_HEADER_0) ||
  237.     (*binArray++) != (MAGIC_HEADER_1))
  238.     {
  239.     return (ERROR); /* bad magic number */
  240.     }
  241. maxbits        = *binArray++; /* set -b from file */
  242. block_compress = maxbits & BLOCK_MASK;
  243. maxbits       &= BIT_MASK;
  244. maxmaxcode     = (1 << maxbits);
  245. if (maxbits > BITS)
  246.     return (ERROR); /* compressed with too many bits per code */
  247.         }
  248.     /* tune hash table size for small files -- ad hoc */
  249. #if HSIZE > 5003
  250.     if (fsize < (1 << 12))
  251. hsize = 5003;
  252. #if HSIZE > 9001
  253.     else if (fsize < (1 << 13))
  254. hsize = 9001;
  255. #if HSIZE > 18013
  256.     else if (fsize < (1 << 14))
  257. hsize = 18013;
  258. #if HSIZE > 35023
  259.     else if (fsize < (1 << 15))
  260. hsize = 35023;
  261.     else if (fsize < 47000)
  262. hsize = 50021;
  263. #endif /* HSIZE > 35023 */
  264. #endif /* HSIZE > 18013 */
  265. #endif /* HSIZE > 9001 */
  266.     else
  267. #endif /* HSIZE > 5003 */
  268. hsize = HSIZE;
  269.     /* initialize the first 256 entries in the table */
  270.     maxcode = MAXCODE (n_bits = INIT_BITS);
  271.     for (code = 255; code >= 0; code--)
  272.         {
  273. tab_prefix[code] = 0;
  274. tab_suffix[code] = (char_type) code;
  275.         }
  276.     free_ent = ((block_compress) ? FIRST : 256);
  277.     finchar = oldcode = getcode ();
  278.     *(destination++) = (char) finchar;
  279.     while ((code = getcode ()) != -1)
  280.         {
  281. if (code == CLEAR && block_compress)
  282.     {
  283.     for (code = 255; code > 0; code -= 4)
  284.         {
  285. tab_prefix[code-3] = 0;
  286. tab_prefix[code-2] = 0;
  287. tab_prefix[code-1] = 0;
  288. tab_prefix[code]   = 0;
  289.         }
  290.     clear_flg = 1;
  291.     free_ent = FIRST - 1;
  292.     if ((code = getcode ()) == -1) /* Oh, untimely death! */
  293. break;
  294.     }
  295. incode = code;
  296. /* special case for KwKwK string */
  297. if (code >= free_ent)
  298.     {
  299.     stack[--stack_top] = finchar;
  300.     code = oldcode;
  301.     }
  302. /* generate output characters in reverse order */
  303. while (code >= 256)
  304.     {
  305.     stack[--stack_top] = tab_suffix[code];
  306.     code = tab_prefix[code];
  307.     }
  308. stack[--stack_top] = finchar = tab_suffix[code];
  309. /* and put them out in forward order */
  310. for (; stack_top < MAXSTACK; stack_top++)
  311.     *(destination++) = stack[stack_top];
  312. stack_top = MAXSTACK;
  313. /* Generate the new entry */
  314. if ((code = free_ent) < maxmaxcode)
  315.     {
  316.     tab_prefix[code] = (unsigned short) oldcode;
  317.     tab_suffix[code] = finchar;
  318.     free_ent = code + 1;
  319.     }
  320. oldcode = incode; /* remember previous code */
  321.         }
  322.     return (OK);
  323.     }
  324. /*******************************************************************************
  325. *
  326. * getcode - read one code from the compressed image
  327. *
  328. * RETURNS: Code or -1 at end of image.
  329. */
  330. LOCAL code_int getcode (void)
  331.     {
  332.     static char_type buf [BITS];
  333.     FAST code_int code;
  334.     FAST int r_off;
  335.     FAST int bits;
  336.     FAST char_type *bp;
  337.     if (clear_flg > 0 || offset >= size || free_ent > maxcode)
  338.         {
  339. /*
  340.  * If the next entry will be too big for the current code size, then
  341.  * we must increase the size.  This implies reading a new buffer
  342.  * full, too.
  343.  */
  344. if (free_ent > maxcode)
  345.     {
  346.     n_bits++;
  347.     if (n_bits == maxbits)
  348. maxcode = maxmaxcode; /* won't get any bigger now */
  349.     else
  350. maxcode = MAXCODE (n_bits);
  351.     }
  352. if (clear_flg > 0)
  353.     {
  354.     maxcode = MAXCODE (n_bits = INIT_BITS);
  355.     clear_flg = 0;
  356.     }
  357. if (&binArray [n_bits] > binEnd)
  358.     size = binEnd - binArray;
  359. else
  360.     size = n_bits;
  361. if (size <= 0)
  362.     return (-1); /* end of file */
  363. bp = buf;
  364. while (bp < (char_type *) ((int)buf + size))
  365.     *bp++ = *binArray++;
  366. offset = 0;
  367. /* Round size down to integral number of codes */
  368. size = (size << 3) - (n_bits - 1);
  369.         }
  370.     r_off = offset;
  371.     bits  = n_bits;
  372.     /* get to the first byte */
  373.     bp    = buf + (r_off >> 3);
  374.     r_off &= 7;
  375.     /* get first part (low order bits) */
  376.     code  = (*bp++ >> r_off);
  377.     bits -= (8 - r_off);
  378.     r_off = 8 - r_off; /* now, offset into code word */
  379.     /* get any 8 bit parts in the middle (<=1 for up to 16 bits) */
  380.     if (bits >= 8)
  381.         {
  382. code  |= *bp++ << r_off;
  383. r_off += 8;
  384. bits  -= 8;
  385.         }
  386.     /* high order bits */
  387.     code |= (*bp & rmask[bits]) << r_off;
  388.     offset += n_bits;
  389.     return (code);
  390.     }