Skip to content

Commit 82fa770

Browse files
committed
enc: fix several bugs in tree generation
1 parent 64fa857 commit 82fa770

File tree

1 file changed

+33
-19
lines changed

1 file changed

+33
-19
lines changed

huff_enc.c

+33-19
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ bool huff_gen_enc(const uint32_t freq[restrict 256],
6464

6565
/* generate huffman code lengths */
6666
gen_code_lengths(num_sym, freq, codes);
67+
//limit_length(num_sym, codes);
6768

6869
/* generate canonical huffman codes */
6970
gen_canonical_codes(num_sym, codes, info);
@@ -117,31 +118,33 @@ static void get_min_nodes(uint16_t n, const struct node nodes[restrict],
117118
assert(min2_index != NULL);
118119

119120
uint16_t index1 = 0;
120-
uint16_t index2 = 1;
121+
uint16_t index2 = 0;
121122

122123
uint32_t count1 = nodes[0].count;
123-
uint32_t count2 = nodes[1].count;
124-
125-
for (uint16_t i = 2; i < n; i++) {
124+
for (uint16_t i = 1; i < n; i++) {
126125
if (count1 > nodes[i].count) {
127-
if (count1 > count2) {
128-
index2 = index1;
129-
count2 = count1;
130-
}
131-
132-
index1 = i;
133126
count1 = nodes[i].count;
134-
continue;
127+
index1 = i;
135128
}
129+
}
130+
131+
uint32_t count2;
132+
if (index1 == 0) {
133+
count2 = nodes[1].count;
134+
index2 = 1;
135+
} else {
136+
count2 = nodes[0].count;
137+
index2 = 0;
138+
}
136139

137-
if (count2 > nodes[i].count) {
138-
index2 = i;
140+
for (uint16_t i = 1; i < n; i++) {
141+
if (count2 > nodes[i].count && i != index1) {
139142
count2 = nodes[i].count;
143+
index2 = i;
140144
}
141-
142-
assert(index1 != index2);
143145
}
144146

147+
assert(index1 != index2);
145148
assert(index1 < n);
146149
assert(index2 < n);
147150

@@ -176,14 +179,16 @@ static bool gen_code_lengths(uint16_t num_sym, const uint32_t freq[restrict],
176179
assert(freq != NULL);
177180
assert(codes != NULL);
178181

179-
struct node *nodes = malloc((2 * num_sym) * sizeof(struct node));
182+
struct node *nodes = malloc((2 * num_sym - 1) * sizeof(struct node));
180183
size_t node_index = 0;
181184
uint32_t freq_sum = 0;
185+
182186
for (int i = 0; i < 256; i++) {
183187
if (freq[i] == 0)
184188
continue;
185189

186190
freq_sum += freq[i];
191+
187192
codes[node_index].symbol = i;
188193
nodes[node_index] = (struct node) {
189194
.left = NULL,
@@ -197,13 +202,15 @@ static bool gen_code_lengths(uint16_t num_sym, const uint32_t freq[restrict],
197202
assert(0 < node_index && node_index <= 256);
198203

199204
uint16_t border = num_sym;
200-
uint16_t last = 2 * num_sym - 1;
205+
uint16_t last = 2 * num_sym - 2;
201206

202207
while (border > 2) {
203208
uint16_t min1_index;
204209
uint16_t min2_index;
205210

206211
get_min_nodes(border, nodes, &min1_index, &min2_index);
212+
assert(min1_index < border && min2_index < border);
213+
assert(nodes[min1_index].count <= nodes[min2_index].count);
207214

208215
nodes[last] = nodes[min2_index];
209216
nodes[last - 1] = nodes[min1_index];
@@ -219,6 +226,14 @@ static bool gen_code_lengths(uint16_t num_sym, const uint32_t freq[restrict],
219226
last -= 2;
220227
}
221228

229+
if (nodes[0].count > nodes[1].count) {
230+
struct node tmp = nodes[1];
231+
nodes[1] = nodes[0];
232+
nodes[0] = tmp;
233+
}
234+
235+
assert(nodes[0].count <= nodes[1].count);
236+
222237
struct node root = (struct node) {
223238
.left = &nodes[0],
224239
.right = &nodes[1],
@@ -244,14 +259,13 @@ static void gen_canonical_codes(uint16_t num_codes,
244259
for (int i = 0; i < 16; i++) {
245260
uint8_t num_codes_len = 0;
246261
for (int j = 0; j < num_codes; j++) {
262+
assert(codes[j].code_len <= 16);
247263
if (codes[j].code_len != i + 1)
248264
continue;
249265

250266
codes[j].code = code;
251267
code++;
252268
num_codes_len++;
253-
254-
printf("Symbol %2X: %4X - %u\n", codes[j].symbol, codes[j].code, codes[j].code_len);
255269
}
256270

257271
code <<= 1;

0 commit comments

Comments
 (0)