summaryrefslogtreecommitdiffstats
path: root/all_pairs/source/huff_dec/huff_dec.c
diff options
context:
space:
mode:
Diffstat (limited to 'all_pairs/source/huff_dec/huff_dec.c')
-rw-r--r--all_pairs/source/huff_dec/huff_dec.c393
1 files changed, 393 insertions, 0 deletions
diff --git a/all_pairs/source/huff_dec/huff_dec.c b/all_pairs/source/huff_dec/huff_dec.c
new file mode 100644
index 0000000..48bdf4b
--- /dev/null
+++ b/all_pairs/source/huff_dec/huff_dec.c
@@ -0,0 +1,393 @@
1/*
2
3 This program is part of the TACLeBench benchmark suite.
4 Version V 2.0
5
6 Name: huff_dec
7
8 Author: David Bourgin (David.Bourgin@ufrima.imag.fr)
9
10 Function: Example of Huffman decoding
11
12 Source: ftp://turing.imag.fr/pub/compression/ (1994-09-26)
13
14 Original name: dcodhuff.c
15
16 Changes: I/O to char arrays instead of file i/o.
17 Dynamic memory allocation replaced by array.
18
19 License:
20
21The source code files (codrl1.c, dcodrl1.c, codrle2.c, dcodrle2.c, codrle3.c,
22dcodrle3.c, codrle4.c, dcodrle4.c, codhuff.c, dcodhuff.c) are copyrighted.
23They have been uploaded on ftp in turing.imag.fr (129.88.31.7):/pub/compression
24on 22/5/94 and have been modified on 22/9/94.
25(c) David Bourgin - 1994
26The source codes I provide have no buggs (!) but being that I make them
27available for free I have some notes to make. They can change at any time
28without notice. I assume no responsability or liability for any errors or
29inaccurracies, make no warranty of any kind (express, implied or statutory)
30with respect to this publication and expressly disclaim any and all warranties
31of merchantability, fitness for particular purposes. Of course, if you have
32some problems to use the information presented here, I will try to help you if
33I can.
34
35If you include the source codes in your application, here are the conditions:
36- You have to put my name in the header of your source file (not in the
37excutable program if you don't want) (this item is a must)
38- I would like to see your resulting application, if possible (this item is not
39a must, because some applications must remain secret)
40- Whenever you gain money with your application, I would like to receive a very
41little part in order to be encouraged to update my source codes and to develop
42new schemes (this item is not a must)
43
44*/
45
46
47/*
48 Declaration of types
49*/
50
51
52#include "../extra.h"
53typedef struct s_tree {
54 unsigned int byte; /* A byte has to be coded as an unsigned integer to
55 allow a node to have a value over 255 */
56 struct s_tree *left_ptr;
57 struct s_tree *right_ptr;
58} huff_dec_t_tree;
59
60typedef struct {
61 unsigned char bits[32];
62 unsigned int bits_nb;
63 unsigned char presence;
64} t_bin_val;
65
66
67/*
68 Forward declaration of functions
69*/
70
71void huff_dec_init( void );
72int huff_dec_return( void );
73int huff_dec_end_of_data();
74int huff_dec_read_byte();
75void huff_dec_write_byte( char ch );
76unsigned char huff_dec_read_code_1_bit();
77unsigned int huff_dec_read_code_n_bits( unsigned int n );
78void huff_dec_read_header( t_bin_val codes_table[257] );
79huff_dec_t_tree *huff_dec_tree_encoding( t_bin_val codes_table[257],
80 huff_dec_t_tree heap[514] );
81void huff_dec_main( void );
82//int main( void );
83
84
85/*
86 Declaration of global variables
87*/
88
89static int huff_dec_input_pos;
90static int huff_dec_output_pos;
91static char huff_dec_output[1024];
92unsigned char huff_dec_byte_nb_to_read = 0;
93unsigned int huff_dec_val_to_read = 0;
94
95
96/*
97 Initialization- and return-value-related functions
98*/
99
100#define huff_dec_plaintext_len 600
101static const char *huff_dec_plaintext =
102 "You are doubtless asking \"How can I reduce the data size without losing "
103 "some informations?\". It's easy to answer to this question. I'll only take "
104 "an example. I'm sure you have heard about the morse. This system established "
105 "in the 19th century use a scheme very close to the huffman one. In the morse "
106 "you encode the letters to transmit with two kinds of signs. If you encode "
107 "these two sign possibilities in one bit, the symbol 'e' is transmitted in a "
108 "single bit and the symbols 'y' and 'z' need four bits. Look at the symbols "
109 "in the text you are reading, you'll fast understand the compression ratio...";
110
111#define huff_dec_encoded_len 419
112static unsigned char huff_dec_encoded[huff_dec_encoded_len] = {
113 128, 0, 0, 0, 80, 133, 32, 32, 128, 100, 4, 32, 63, 239, 255, 240,
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115 4, 7, 167, 21, 129, 232, 69, 120, 132, 217, 20, 162, 19, 164, 39, 133,
116 252, 138, 105, 20, 194, 19, 129, 240, 172, 138, 248, 150, 11, 11, 240, 201,
117 68, 64, 114, 53, 17, 42, 37, 195, 128, 212, 116, 194, 41, 98, 52, 51,
118 12, 132, 112, 244, 3, 36, 33, 52, 39, 135, 164, 33, 62, 156, 87, 14,
119 110, 22, 87, 50, 85, 198, 99, 142, 140, 194, 81, 78, 158, 84, 129, 254,
120 129, 248, 110, 179, 159, 192, 145, 133, 184, 184, 28, 210, 96, 146, 73, 10,
121 226, 21, 83, 152, 74, 13, 111, 132, 199, 202, 219, 241, 74, 193, 167, 105,
122 222, 31, 147, 6, 55, 31, 129, 40, 232, 52, 153, 160, 148, 18, 36, 197,
123 45, 216, 202, 86, 30, 31, 177, 90, 133, 138, 248, 23, 81, 195, 160, 100,
124 215, 93, 50, 185, 225, 251, 23, 6, 230, 225, 229, 112, 71, 80, 96, 141,
125 205, 176, 230, 85, 196, 9, 24, 93, 90, 121, 225, 76, 68, 152, 63, 25,
126 107, 140, 101, 204, 214, 77, 26, 194, 96, 18, 48, 77, 210, 137, 1, 253,
127 4, 230, 248, 56, 240, 224, 111, 163, 95, 10, 12, 223, 7, 234, 167, 129,
128 40, 36, 96, 135, 125, 245, 250, 2, 198, 120, 127, 0, 145, 133, 213, 167,
129 135, 149, 195, 67, 235, 108, 9, 24, 87, 17, 102, 152, 37, 4, 222, 131,
130 188, 144, 73, 36, 128, 73, 20, 81, 152, 177, 133, 248, 28, 165, 131, 120,
131 127, 240, 242, 184, 104, 125, 109, 129, 35, 30, 4, 145, 65, 202, 88, 9,
132 138, 103, 44, 205, 100, 167, 24, 152, 11, 24, 51, 37, 66, 9, 24, 31,
133 174, 202, 212, 49, 152, 18, 96, 155, 208, 119, 146, 45, 97, 48, 56, 28,
134 194, 90, 224, 204, 144, 232, 176, 36, 96, 126, 187, 43, 83, 12, 121, 129,
135 209, 96, 197, 35, 2, 54, 176, 249, 92, 208, 204, 145, 188, 41, 170, 180,
136 71, 16, 36, 96, 126, 187, 43, 83, 19, 0, 145, 129, 100, 209, 15, 43,
137 135, 55, 6, 238, 180, 194, 90, 17, 229, 115, 21, 168, 251, 140, 131, 162,
138 217, 166, 93, 22, 4, 140, 31, 91, 166, 55, 25, 202, 192, 111, 20, 171,
139 207, 39, 192,
140};
141
142
143void huff_dec_init( void )
144{
145 huff_dec_input_pos = 0;
146 huff_dec_output_pos = 0;
147}
148
149
150int huff_dec_return( void )
151{
152 int i;
153 _Pragma( "loopbound min 1 max 600" )
154 for ( i = 0; i < huff_dec_plaintext_len; i++ ) {
155 if ( huff_dec_plaintext[i] != huff_dec_output[i] ) return i + 1;
156 }
157 return 0;
158}
159
160
161/*
162 Input / output functions
163*/
164
165int huff_dec_end_of_data()
166{
167 return huff_dec_input_pos >= huff_dec_encoded_len;
168}
169
170
171int huff_dec_read_byte()
172{
173 return huff_dec_encoded[huff_dec_input_pos++];
174}
175
176
177void huff_dec_write_byte( char ch )
178{
179 huff_dec_output[huff_dec_output_pos++] = ch;
180}
181
182
183unsigned char huff_dec_read_code_1_bit()
184/* Returned parameters: Returns an unsigned integer with the 0-bit (on the
185 right of the integer) valid
186 Action: Reads the next bit in the stream of data to compress
187 Errors: An input/output error could disturb the running of the program
188 The source must have enough bits to read
189*/
190{
191 if ( huff_dec_byte_nb_to_read ) {
192 huff_dec_byte_nb_to_read--;
193 return ( ( huff_dec_val_to_read >> huff_dec_byte_nb_to_read ) & 1 );
194 } else {
195 huff_dec_val_to_read = huff_dec_read_byte();
196 huff_dec_byte_nb_to_read = 7;
197 return ( ( huff_dec_val_to_read >> 7 ) & 1 );
198 }
199}
200
201
202unsigned int huff_dec_read_code_n_bits( unsigned int n )
203/* Returned parameters: Returns an unsigned integer with the n-bits (on the
204 right of the integer) valid
205 Action: Reads the next n bits in the stream of data to compress
206 Errors: An input/output error could disturb the running of the program
207 The source must have enough bits to read
208*/
209{
210 unsigned int result = 0;
211 unsigned i = n;
212
213 _Pragma ( "loopbound min 1 max 1" )
214 while ( i ) {
215 _Pragma ( "loopbound min 0 max 2" )
216 while ( ( huff_dec_byte_nb_to_read < 9 ) && ( !huff_dec_end_of_data() ) ) {
217 huff_dec_val_to_read = ( huff_dec_val_to_read << 8 ) + huff_dec_read_byte();
218 huff_dec_byte_nb_to_read += 8;
219 }
220 if ( i >= huff_dec_byte_nb_to_read ) {
221 result = ( result << huff_dec_byte_nb_to_read ) + huff_dec_val_to_read;
222 i -= huff_dec_byte_nb_to_read;
223 huff_dec_byte_nb_to_read = 0;
224 } else {
225 result = ( result << i ) + ( ( huff_dec_val_to_read >>
226 ( huff_dec_byte_nb_to_read - i ) ) & ( ( 1 << i ) - 1 ) );
227 huff_dec_byte_nb_to_read -= i;
228 i = 0;
229 }
230 }
231 return ( result );
232}
233
234
235void huff_dec_read_header( t_bin_val codes_table[257] )
236/* Returned parameters: The contain of 'codes_table' is modified
237 Action: Rebuilds the binary encoding array by using the header
238 Errors: An input/output error could disturb the running of the program
239*/
240{
241 unsigned int i, j;
242 unsigned num_byte;
243
244 _Pragma ( "loopbound min 257 max 257" )
245 for ( i = 0; i < 257; i++ ) {
246 codes_table[i].bits_nb = 0;
247 _Pragma ( "loopbound min 32 max 32" )
248 for ( j = 0; j < 32; j++ ) {
249 codes_table[i].bits[j] = 0;
250 }
251 }
252
253 /* == Decoding of the first part of the header === */
254 if ( huff_dec_read_code_1_bit() )
255 /* First bit=0 => Present bytes coded on n*8 bits
256 =1 => Present bytes coded on 256 bits */
257 _Pragma ( "loopbound min 256 max 256" )
258 for ( i = 0; i <= 255; i++ )
259 codes_table[i].presence = huff_dec_read_code_1_bit();
260 else {
261 i = huff_dec_read_code_n_bits( 5 ) + 1;
262 _Pragma ( "loopbound min 1 max 32" )
263 while ( i ) {
264 codes_table[huff_dec_read_code_n_bits( 8 )].presence = 1;
265 i--;
266 }
267 }
268 codes_table[256].presence = 1;
269 /* Presence of a fictive 256-byte is enforced! */
270
271 /* == Decoding the second part of the header == */
272 _Pragma ( "loopbound min 257 max 257" )
273 for ( i = 0; i <= 256; i++ )
274 if ( codes_table[i].presence ) {
275 if ( huff_dec_read_code_1_bit() )
276 /* First bit=0 => 5 bits of binary length-1 followed by a binary word
277 =1 => 8 bits of binary length-1 followed by a binary word */
278 j = huff_dec_read_code_n_bits( 8 ) + 1;
279 else j = huff_dec_read_code_n_bits( 5 ) + 1;
280 codes_table[i].bits_nb = j;
281 /* Reading of a binary word */
282 num_byte = ( j - 1 ) >> 3;
283 if ( j & 7 ) {
284 /* Reads the bits that takes less than one byte */
285 codes_table[i].bits[num_byte] =
286 ( unsigned char )huff_dec_read_code_n_bits( j & 7 );
287 j -= j & 7;
288 num_byte--;
289 }
290
291 _Pragma ( "loopbound min 0 max 1" )
292 while ( j >= 8 ) {
293 /* Reads the bits that takes one byte, at least */
294 codes_table[i].bits[num_byte] =
295 ( unsigned char )huff_dec_read_code_n_bits( 8 );
296 j -= 8;
297 num_byte--;
298 }
299 }
300}
301
302
303huff_dec_t_tree *huff_dec_tree_encoding( t_bin_val codes_table[257],
304 huff_dec_t_tree heap[514] )
305/* Returned parameters: A binary tree is returned
306 Action: Returns the decoding binary tree built from 'codes_table'
307 Errors: None
308*/
309{
310 unsigned int i;
311 unsigned int j;
312 unsigned int heap_top = 0;
313 huff_dec_t_tree *ptr_tree;
314 huff_dec_t_tree *current_node;
315
316 ptr_tree = &heap[heap_top++];
317 ptr_tree->byte = 257;
318 ptr_tree->left_ptr = 0;
319 ptr_tree->right_ptr = 0;
320 _Pragma ( "loopbound min 257 max 257" )
321 for ( i = 0; i <= 256; i++ ) {
322 _Pragma ( "loopbound min 0 max 9" )
323 for ( current_node = ptr_tree, j = codes_table[i].bits_nb; j; j-- ) {
324 if ( codes_table[i].bits[( j - 1 ) >> 3] & ( 1 << ( (
325 j - 1 ) & 7 ) ) )
326 if ( current_node->left_ptr == 0 ) {
327 current_node->left_ptr = &heap[heap_top++];
328 current_node = current_node->left_ptr;
329 current_node->left_ptr = 0;
330 current_node->right_ptr = 0;
331 } else current_node = current_node->left_ptr;
332 else
333 if ( current_node->right_ptr == 0 ) {
334 current_node->right_ptr = &heap[heap_top++];
335 current_node = current_node->right_ptr;
336 current_node->left_ptr = 0;
337 current_node->right_ptr = 0;
338 } else current_node = current_node->right_ptr;
339 if ( j == 1 )
340 current_node->byte = i;
341 else current_node->byte = 257;
342 }
343 };
344 return ( ptr_tree );
345}
346
347
348void _Pragma( "entrypoint" ) huff_dec_main( void )
349/* Returned parameters: None
350 Action: Decompresses with Huffman method all bytes read by the function
351 'read_code_1_bit' and 'read_code_n_bits'
352 Errors: An input/output error could disturb the running of the program
353*/
354{
355 t_bin_val encoding_table[257];
356 huff_dec_t_tree heap[514]; /* space for dynamically allocated nodes */
357 huff_dec_t_tree *ptr_tree;
358 huff_dec_t_tree *current_node;
359
360 if ( !huff_dec_end_of_data() ) { /* Are there data to compress? */
361 huff_dec_read_header( encoding_table );
362 ptr_tree = huff_dec_tree_encoding( encoding_table, heap );
363 _Pragma ( "loopbound min 602 max 602" )
364 do {
365 current_node = ptr_tree;
366 _Pragma ( "loopbound min 3 max 9" )
367 while ( current_node->byte == 257 )
368 if ( huff_dec_read_code_1_bit() )
369 /* Bit=1 => Got to left in the node of the tree
370 =0 => Got to right in the node of the tree */
371 current_node = current_node->left_ptr;
372 else current_node = current_node->right_ptr;
373 if ( current_node->byte <= 255 )
374 huff_dec_write_byte( current_node->byte );
375 } while ( current_node->byte != 256 );
376 }
377}
378
379
380int main( int argc, char **argv )
381{
382 //SET_UP
383 int jobsComplete;
384 int maxJobs=5;
385 for (jobsComplete=-1; jobsComplete<maxJobs; jobsComplete++){
386 // START_LOOP
387 huff_dec_init();
388 huff_dec_main();
389 // STOP_LOOP
390 }
391 //WRITE_TO_FILE
392 return ( huff_dec_return() );
393}