2 * @file libavcodec/huffman.c
3 * huffman tree builder and VLC generator
4 * Copyright (c) 2006 Konstantin Shishkov
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 /* symbol for Huffman tree node */
31 static void get_tree_codes(uint32_t *bits
, int16_t *lens
, uint8_t *xlat
, Node
*nodes
, int node
, uint32_t pfx
, int pl
, int *pos
, int no_zero_count
)
36 if(s
!= HNODE
|| (no_zero_count
&& !nodes
[node
].count
)){
44 get_tree_codes(bits
, lens
, xlat
, nodes
, nodes
[node
].n0
, pfx
, pl
, pos
,
47 get_tree_codes(bits
, lens
, xlat
, nodes
, nodes
[node
].n0
+1, pfx
, pl
, pos
,
52 static int build_huff_tree(VLC
*vlc
, Node
*nodes
, int head
, int flags
)
54 int no_zero_count
= !(flags
& FF_HUFFMAN_FLAG_ZERO_COUNT
);
60 get_tree_codes(bits
, lens
, xlat
, nodes
, head
, 0, 0, &pos
, no_zero_count
);
61 return init_vlc_sparse(vlc
, 9, pos
, lens
, 2, 2, bits
, 4, 4, xlat
, 1, 1, 0);
66 * nodes size must be 2*nb_codes
67 * first nb_codes nodes.count must be set
69 int ff_huff_build_tree(AVCodecContext
*avctx
, VLC
*vlc
, int nb_codes
,
70 Node
*nodes
, HuffCmp cmp
, int flags
)
76 for(i
= 0; i
< nb_codes
; i
++){
79 sum
+= nodes
[i
].count
;
83 av_log(avctx
, AV_LOG_ERROR
, "Too high symbol frequencies. Tree construction is not possible\n");
86 qsort(nodes
, nb_codes
, sizeof(Node
), cmp
);
88 nodes
[nb_codes
*2-1].count
= 0;
89 for(i
= 0; i
< nb_codes
*2-1; i
+= 2){
90 nodes
[cur_node
].sym
= HNODE
;
91 nodes
[cur_node
].count
= nodes
[i
].count
+ nodes
[i
+1].count
;
92 nodes
[cur_node
].n0
= i
;
93 for(j
= cur_node
; j
> 0; j
--){
94 if(nodes
[j
].count
> nodes
[j
-1].count
||
95 (nodes
[j
].count
== nodes
[j
-1].count
&&
96 (!(flags
& FF_HUFFMAN_FLAG_HNODE_FIRST
) ||
97 nodes
[j
].n0
==j
-1 || nodes
[j
].n0
==j
-2 ||
98 (nodes
[j
].sym
!=HNODE
&& nodes
[j
-1].sym
!=HNODE
))))
100 FFSWAP(Node
, nodes
[j
], nodes
[j
-1]);
104 if(build_huff_tree(vlc
, nodes
, nb_codes
*2-2, flags
) < 0){
105 av_log(avctx
, AV_LOG_ERROR
, "Error building tree\n");