diff options
Diffstat (limited to 'baseline/source/huff_dec/huff_dec.c')
-rw-r--r-- | baseline/source/huff_dec/huff_dec.c | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/baseline/source/huff_dec/huff_dec.c b/baseline/source/huff_dec/huff_dec.c new file mode 100644 index 0000000..48bdf4b --- /dev/null +++ b/baseline/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 | |||
21 | The source code files (codrl1.c, dcodrl1.c, codrle2.c, dcodrle2.c, codrle3.c, | ||
22 | dcodrle3.c, codrle4.c, dcodrle4.c, codhuff.c, dcodhuff.c) are copyrighted. | ||
23 | They have been uploaded on ftp in turing.imag.fr (129.88.31.7):/pub/compression | ||
24 | on 22/5/94 and have been modified on 22/9/94. | ||
25 | (c) David Bourgin - 1994 | ||
26 | The source codes I provide have no buggs (!) but being that I make them | ||
27 | available for free I have some notes to make. They can change at any time | ||
28 | without notice. I assume no responsability or liability for any errors or | ||
29 | inaccurracies, make no warranty of any kind (express, implied or statutory) | ||
30 | with respect to this publication and expressly disclaim any and all warranties | ||
31 | of merchantability, fitness for particular purposes. Of course, if you have | ||
32 | some problems to use the information presented here, I will try to help you if | ||
33 | I can. | ||
34 | |||
35 | If 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 | ||
37 | excutable 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 | ||
39 | a must, because some applications must remain secret) | ||
40 | - Whenever you gain money with your application, I would like to receive a very | ||
41 | little part in order to be encouraged to update my source codes and to develop | ||
42 | new schemes (this item is not a must) | ||
43 | |||
44 | */ | ||
45 | |||
46 | |||
47 | /* | ||
48 | Declaration of types | ||
49 | */ | ||
50 | |||
51 | |||
52 | #include "../extra.h" | ||
53 | typedef 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 | |||
60 | typedef 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 | |||
71 | void huff_dec_init( void ); | ||
72 | int huff_dec_return( void ); | ||
73 | int huff_dec_end_of_data(); | ||
74 | int huff_dec_read_byte(); | ||
75 | void huff_dec_write_byte( char ch ); | ||
76 | unsigned char huff_dec_read_code_1_bit(); | ||
77 | unsigned int huff_dec_read_code_n_bits( unsigned int n ); | ||
78 | void huff_dec_read_header( t_bin_val codes_table[257] ); | ||
79 | huff_dec_t_tree *huff_dec_tree_encoding( t_bin_val codes_table[257], | ||
80 | huff_dec_t_tree heap[514] ); | ||
81 | void huff_dec_main( void ); | ||
82 | //int main( void ); | ||
83 | |||
84 | |||
85 | /* | ||
86 | Declaration of global variables | ||
87 | */ | ||
88 | |||
89 | static int huff_dec_input_pos; | ||
90 | static int huff_dec_output_pos; | ||
91 | static char huff_dec_output[1024]; | ||
92 | unsigned char huff_dec_byte_nb_to_read = 0; | ||
93 | unsigned 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 | ||
101 | static 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 | ||
112 | static 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 | |||
143 | void huff_dec_init( void ) | ||
144 | { | ||
145 | huff_dec_input_pos = 0; | ||
146 | huff_dec_output_pos = 0; | ||
147 | } | ||
148 | |||
149 | |||
150 | int 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 | |||
165 | int huff_dec_end_of_data() | ||
166 | { | ||
167 | return huff_dec_input_pos >= huff_dec_encoded_len; | ||
168 | } | ||
169 | |||
170 | |||
171 | int huff_dec_read_byte() | ||
172 | { | ||
173 | return huff_dec_encoded[huff_dec_input_pos++]; | ||
174 | } | ||
175 | |||
176 | |||
177 | void huff_dec_write_byte( char ch ) | ||
178 | { | ||
179 | huff_dec_output[huff_dec_output_pos++] = ch; | ||
180 | } | ||
181 | |||
182 | |||
183 | unsigned 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 | |||
202 | unsigned 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 | |||
235 | void 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 | |||
303 | huff_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 | |||
348 | void _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 | |||
380 | int 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 | } | ||