@@ -35,6 +35,8 @@ static bool gen_code_lengths(uint16_t num_sym, const uint32_t freq[restrict],
35
35
static void gen_canonical_codes (uint16_t num_codes ,
36
36
struct huff_code codes [restrict],
37
37
struct huff_enc_info * restrict info );
38
+ static bool limit_length (uint16_t num_codes , struct huff_code codes [restrict],
39
+ uint8_t limit );
38
40
39
41
bool huff_gen_enc (const uint32_t freq [restrict 256 ],
40
42
struct huff_enc * restrict encoder ,
@@ -64,7 +66,7 @@ bool huff_gen_enc(const uint32_t freq[restrict 256],
64
66
65
67
/* generate huffman code lengths */
66
68
gen_code_lengths (num_sym , freq , codes );
67
- // limit_length(num_sym, codes);
69
+ limit_length (num_sym , codes , 16 );
68
70
69
71
/* generate canonical huffman codes */
70
72
gen_canonical_codes (num_sym , codes , info );
@@ -156,9 +158,6 @@ static void set_len(const struct node *node, uint8_t depth)
156
158
{
157
159
assert (node != NULL );
158
160
159
- if (depth > 16 ) {
160
- fprintf (stderr , "Warning: Code length over 16!\n" );
161
- }
162
161
if (node -> left == NULL && node -> right == NULL ) {
163
162
assert (node -> code != NULL );
164
163
node -> code -> code_len = depth ;
@@ -249,6 +248,68 @@ static bool gen_code_lengths(uint16_t num_sym, const uint32_t freq[restrict],
249
248
return true;
250
249
}
251
250
251
+ static int len_cmp (const void * left , const void * right )
252
+ {
253
+ return ((const struct huff_code * )left )-> code_len -
254
+ ((const struct huff_code * )right )-> code_len ;
255
+ }
256
+
257
+ static bool limit_length (uint16_t num_codes , struct huff_code codes [restrict],
258
+ uint8_t limit )
259
+ {
260
+ assert (num_codes > 0 );
261
+ assert (codes != NULL );
262
+ assert (limit > 1 );
263
+
264
+ // sort by code_len
265
+ qsort (codes , num_codes , sizeof (struct huff_code ), len_cmp );
266
+
267
+ const uint32_t n = 1 << limit ;
268
+
269
+ uint32_t kraft_sum = 0 ;
270
+
271
+ for (uint16_t i = 0 ; i < num_codes ; i ++ ) {
272
+ if (codes [i ].code_len > limit )
273
+ codes [i ].code_len = limit ;
274
+ kraft_sum += n >> codes [i ].code_len ;
275
+ }
276
+
277
+ if (kraft_sum > n ) {
278
+ for (uint16_t i = 0 ; i < num_codes ; i ++ ) {
279
+ uint16_t index = num_codes - i - 1 ;
280
+ if (codes [index ].code_len == limit )
281
+ continue ;
282
+
283
+ if (kraft_sum <= n )
284
+ break ;
285
+
286
+ codes [index ].code_len ++ ;
287
+ kraft_sum -= n >> codes [index ].code_len ;
288
+ }
289
+ }
290
+
291
+ if (kraft_sum < n ) {
292
+ uint32_t kraft_diff = n - kraft_sum ;
293
+
294
+ for (uint16_t i = 0 ; i < num_codes ; i ++ ) {
295
+ if (codes [i ].code_len == 1 )
296
+ continue ;
297
+
298
+ if (n >> (codes [i ].code_len ) > kraft_diff )
299
+ continue ;
300
+
301
+ if (kraft_sum == n || kraft_diff == 0 )
302
+ break ;
303
+
304
+ kraft_sum += n >> codes [i ].code_len ;
305
+ kraft_diff -= n >> codes [i ].code_len ;
306
+ codes [i ].code_len -- ;
307
+ }
308
+ }
309
+
310
+ return true;
311
+ }
312
+
252
313
static void gen_canonical_codes (uint16_t num_codes ,
253
314
struct huff_code codes [restrict],
254
315
struct huff_enc_info * restrict info ) {
0 commit comments