1 /*
2 * Copyright (c) 2006 Konstantin Shishkov
3 * Copyright (c) 2007 Loren Merritt
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * huffman tree builder and VLC generator
25 */
26
27 #include <stdint.h>
28
34
37
38 /* symbol for Huffman tree node */
40
42 union {
44 uint16_t
dummy;
// exists solely to ensure alignof(HeapElem) >= alignof(uint16_t)
45 };
48
50 {
51 while (root * 2 + 1 <
size) {
52 int child = root * 2 + 1;
54 child++;
57 root = child;
58 } else
59 break;
60 }
61 }
62
64 {
65 int *up;
69 sizeof(*
h) + 2 *
sizeof(up) + 2 *
sizeof(
len) +
sizeof(
map));
72 up = (
int*)(
h + stats_size);
73 // map is suitably aligned because up uses an even number of elements
74 // and alignof(uint16_t) is either 1 or 2.
75 map = (uint16_t*)(up + 2 * stats_size);
76 len = (uint8_t*)(
map + stats_size);
77
81
82 for (
i = 0;
i<stats_size;
i++) {
86 }
87
92 }
93 for (
i =
size / 2 - 1;
i >= 0;
i--)
95
96 for (next =
size; next <
size * 2 - 1; next++) {
97 // merge the two smallest entries, and put it back in the heap
98 uint64_t min1v =
h[0].val;
100 h[0].val = INT64_MAX;
102 up[
h[0].name] = next;
106 }
107
114 }
116 }
119 }
120
122 Node *nodes,
int node,
int pl,
int *
pos,
int no_zero_count)
123 {
125
127 if (
s !=
HNODE || (no_zero_count && !nodes[node].count)) {
130 (*pos)++;
131 } else {
132 pl++;
137 }
138 }
139
141 {
143 int8_t lens[256];
144 uint8_t xlat[256];
146
148 &
pos, no_zero_count);
150 xlat, 1, 1, 0, 0, logctx);
151 }
152
153
154 /**
155 * nodes size must be 2*nb_codes
156 * first nb_codes nodes.count must be set
157 */
160 {
162 int cur_node;
164
165 for (
i = 0;
i < nb_codes;
i++) {
169 }
170
171 if (sum >> 31) {
173 "Too high symbol frequencies. "
174 "Tree construction is not possible\n");
175 return -1;
176 }
178 cur_node = nb_codes;
179 nodes[nb_codes*2-1].
count = 0;
180 for (
i = 0;
i < nb_codes * 2 - 1;
i += 2) {
182 // find correct place to insert new node, and
183 // make space for the new node while at it
184 for(j = cur_node; j >
i + 2; j--){
185 if(cur_count > nodes[j-1].count ||
186 (cur_count == nodes[j-1].count &&
188 break;
189 nodes[j] = nodes[j - 1];
190 }
192 nodes[j].
count = cur_count;
194 cur_node++;
195 }
198 return -1;
199 }
200 return 0;
201 }