LZW.C 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  12. */
  13. /*
  14. * $Source: f:/miner/source/pslib/rcs/lzw.c $
  15. * $Revision: 1.8 $
  16. * $Author: john $
  17. * $Date: 1994/02/01 13:23:51 $
  18. *
  19. * Based on lzw15v.c from Data Compression book.
  20. * CompressFile and Expandfile have been replaced by cfread and cfwrite.
  21. *
  22. * $Log: lzw.c $
  23. * Revision 1.8 1994/02/01 13:23:51 john
  24. * *** empty log message ***
  25. *
  26. * Revision 1.7 1993/10/22 17:50:43 yuan
  27. * Fixed the hard to track down bug
  28. *
  29. * Revision 1.6 1993/10/18 18:00:13 yuan
  30. * Fixed memory alloc errors.
  31. *
  32. * Revision 1.5 1993/09/21 17:22:24 yuan
  33. * *** empty log message ***
  34. *
  35. * Revision 1.4 1993/09/21 17:16:25 yuan
  36. * cleaning up
  37. *
  38. * Revision 1.3 1993/09/14 13:11:57 yuan
  39. * cfread and cfwrite have been changed into lzw_expand and lzw_compress.
  40. * the new cfread and cfwrite functions are now in library.c
  41. * lzw_compress returns the compressed buffer and a parameter *size.
  42. *
  43. * Revision 1.2 1993/09/09 17:45:56 yuan
  44. * tab added to ERROR messages
  45. *
  46. * Revision 1.1 1993/09/08 16:15:03 yuan
  47. * Initial revision
  48. *
  49. * Revision 1.3 1993/07/24 19:05:22 yuan
  50. * *** empty log message ***
  51. *
  52. * Revision 1.2 1993/07/22 11:27:29 yuan
  53. * No change
  54. *
  55. * Revision 1.1 1993/07/21 15:28:48 matt
  56. * Initial revision
  57. *
  58. *
  59. */
  60. #pragma off (unreferenced)
  61. static char rcsid[] = "$Id: lzw.c 1.8 1994/02/01 13:23:51 john Exp $";
  62. #pragma on (unreferenced)
  63. #include <stdio.h>
  64. #include <stdlib.h>
  65. #include <string.h>
  66. #include "library.h"
  67. #include "mem.h"
  68. //#define DEBUG_ON 1
  69. //#include "error.h"
  70. #define BITS 15
  71. #define MAX_CODE ( ( 1 << BITS ) - 1 )
  72. #define TABLE_SIZE 35023L
  73. #define END_OF_STREAM 256
  74. #define BUMP_CODE 257
  75. #define FLUSH_CODE 258
  76. #define FIRST_CODE 259
  77. #define UNUSED -1
  78. unsigned int find_child_node( int parent_code, int child_character );
  79. unsigned int decode_string( unsigned int offset, unsigned int code );
  80. char *CompressionName = "LZW 15 Bit Variable Rate Encoder";
  81. char *Usage = "in-file out-file";
  82. typedef struct {
  83. int code_value;
  84. int parent_code;
  85. char character;
  86. } DICTIONARY;
  87. DICTIONARY * dict;
  88. char * decode_stack;
  89. unsigned int next_code;
  90. int current_code_bits;
  91. unsigned int next_bump_code;
  92. void InitializeDictionary()
  93. {
  94. unsigned int i;
  95. for ( i = 0 ; i < TABLE_SIZE ; i++ )
  96. dict[i].code_value = UNUSED;
  97. next_code = FIRST_CODE;
  98. current_code_bits = 9;
  99. next_bump_code = 511;
  100. }
  101. void InitializeStorage()
  102. {
  103. //MALLOC( dict, DICTIONARY, TABLE_SIZE );//won't compile, hack below -KRB
  104. //MALLOC( decode_stack, char, TABLE_SIZE );
  105. dict = (DICTIONARY *)malloc(TABLE_SIZE*sizeof(DICTIONARY));
  106. decode_stack = (char *)malloc(TABLE_SIZE*sizeof(char));
  107. }
  108. void FreeStorage()
  109. {
  110. free(dict);
  111. free(decode_stack);
  112. }
  113. ubyte *lzw_compress( ubyte *inputbuf, ubyte *outputbuf, int input_size, int *output_size ) {
  114. BIT_BUF *output;
  115. int character;
  116. int string_code;
  117. unsigned int index;
  118. int i;
  119. output = OpenOutputBitBuf();
  120. if ( outputbuf == NULL ) {
  121. //MALLOC( output->buf, ubyte, input_size); //Another compile hack -KRB
  122. output->buf = (ubyte *)malloc(input_size*sizeof(ubyte));
  123. if (output->buf == NULL) {
  124. printf(" ERROR : OpenOutputBitBuf - Not enough memory to read buffer.\n");
  125. exit(1);
  126. }
  127. outputbuf = output->buf;
  128. } else output->buf = outputbuf;
  129. InitializeStorage();
  130. InitializeDictionary();
  131. string_code = ( *inputbuf++ );
  132. for ( i=0 ; i<input_size ; i++ ) {
  133. if (output->current_byte+4 >= input_size) {
  134. CloseOutputBitBuf( output );
  135. FreeStorage();
  136. free( outputbuf );
  137. *output_size = -1;
  138. return NULL;
  139. }
  140. character = ( *inputbuf++ );
  141. index = find_child_node( string_code, character );
  142. if ( dict[ index ].code_value != - 1 )
  143. string_code = dict[ index ].code_value;
  144. else {
  145. dict[ index ].code_value = next_code++;
  146. dict[ index ].parent_code = string_code;
  147. dict[ index ].character = (char) character;
  148. OutputBits( output,
  149. (unsigned long) string_code, current_code_bits );
  150. string_code = character;
  151. if ( next_code > MAX_CODE ) {
  152. OutputBits( output,
  153. (unsigned long) FLUSH_CODE, current_code_bits );
  154. InitializeDictionary();
  155. } else if ( next_code > next_bump_code ) {
  156. OutputBits( output,
  157. (unsigned long) BUMP_CODE, current_code_bits );
  158. current_code_bits++;
  159. next_bump_code <<= 1;
  160. next_bump_code |= 1;
  161. }
  162. }
  163. }
  164. OutputBits( output, (unsigned long) string_code, current_code_bits );
  165. OutputBits( output, (unsigned long) END_OF_STREAM, current_code_bits);
  166. *output_size = output->current_byte+1;
  167. //printf("Outputsize %d\n", *output_size);
  168. CloseOutputBitBuf( output );
  169. FreeStorage();
  170. //mem_validate_heap();
  171. return outputbuf;
  172. }
  173. ubyte *lzw_expand( ubyte *inputbuf, ubyte *outputbuf, int length ) {
  174. BIT_BUF *input;
  175. unsigned int new_code;
  176. unsigned int old_code;
  177. int character;
  178. unsigned int count;
  179. int counter;
  180. //printf("Input Size %d\n", length);
  181. input = OpenInputBitBuf( inputbuf );
  182. if ( outputbuf == NULL )
  183. //MALLOC(outputbuf, ubyte, length);//Another hack for compiling -KRB
  184. outputbuf = (ubyte *)malloc(length*sizeof(ubyte));
  185. InitializeStorage();
  186. counter = 0;
  187. for ( ; ; ) {
  188. //mem_validate_heap();
  189. InitializeDictionary();
  190. old_code = (unsigned int) InputBits( input, current_code_bits );
  191. if ( old_code == END_OF_STREAM ) {
  192. CloseInputBitBuf( input );
  193. return outputbuf;
  194. }
  195. character = old_code;
  196. if (counter<length) {
  197. outputbuf[counter++] = ( ubyte ) old_code;
  198. } else {
  199. printf( "ERROR:Tried to write %d\n", old_code );
  200. exit(1);
  201. }
  202. for ( ; ; ) {
  203. //mem_validate_heap();
  204. new_code = (unsigned int) InputBits( input, current_code_bits );
  205. if ( new_code == END_OF_STREAM ) {
  206. //printf("\nEND OF STREAM at %d bytes\n", counter);
  207. CloseInputBitBuf( input );
  208. FreeStorage();
  209. return outputbuf;
  210. }
  211. if ( new_code == FLUSH_CODE )
  212. break;
  213. if ( new_code == BUMP_CODE ) {
  214. current_code_bits++;
  215. continue;
  216. }
  217. if ( new_code >= next_code ) {
  218. decode_stack[ 0 ] = (char) character;
  219. count = decode_string( 1, old_code );
  220. }
  221. else {
  222. count = decode_string( 0, new_code );
  223. }
  224. character = decode_stack[ count - 1 ];
  225. while ( count > 0 ) {
  226. // This lets the case counter==length pass through.
  227. // This is a hack.
  228. if (counter<length) {
  229. outputbuf[counter++] = ( ubyte ) decode_stack[ --count ];
  230. } else if (counter>length) {
  231. printf( "ERROR:Tried to write %d\n", decode_stack[ --count ] );
  232. exit(1);
  233. } else
  234. count--;
  235. }
  236. dict[ next_code ].parent_code = old_code;
  237. dict[ next_code ].character = (char) character;
  238. next_code++;
  239. old_code = new_code;
  240. }
  241. }
  242. }
  243. unsigned int find_child_node( int parent_code, int child_character ) {
  244. unsigned int index;
  245. int offset;
  246. index = ( child_character << ( BITS - 8 ) ) ^ parent_code;
  247. if ( index == 0 )
  248. offset = 1;
  249. else
  250. offset = TABLE_SIZE - index;
  251. for ( ; ; ) {
  252. if ( dict[ index ].code_value == UNUSED )
  253. return( (unsigned int) index );
  254. if ( dict[ index ].parent_code == parent_code &&
  255. dict[ index ].character == (char) child_character )
  256. return( index );
  257. if ( (int) index >= offset )
  258. index -= offset;
  259. else
  260. index += TABLE_SIZE - offset;
  261. }
  262. }
  263. unsigned int decode_string( unsigned int count, unsigned int code ) {
  264. while ( code > 255 ) {
  265. decode_stack[ count++ ] = dict[ code ].character;
  266. code = dict[ code ].parent_code;
  267. }
  268. decode_stack[ count++ ] = (char) code;
  269. return( count );
  270. }
  271.