diff options
author | Reimar Döffinger <Reimar.Doeffinger@gmx.de> | 2012-01-30 00:23:59 +0400 |
---|---|---|
committer | Reimar Döffinger <Reimar.Doeffinger@gmx.de> | 2012-01-30 21:39:08 +0400 |
commit | 6166bf3cbe99d687b15fc5a84bd6d399d6bab3fa (patch) | |
tree | dfbe502ea5378a1df0a47945dc082dd58fdef8b3 | |
parent | 5f27374c1b397c718c9c9a28509aab40f681d9da (diff) |
Deobfuscate ff_huff_build_tree.
I have no idea what the idea was behind the original code,
but the new code is equivalent to it.
In that loop that places the new node nodes[j] contains
always the data of the new node (since the steps are always
in order: FFSWAP copies node[j] to node[j-1], j is decremented).
Thus nodes[j].no == i and nodes[j].sym == HNODE.
make fate still passes and contains VP6 samples which use
FF_HUFFMAN_FLAG_HNODE_FIRST.
Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
-rw-r--r-- | libavcodec/huffman.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/libavcodec/huffman.c b/libavcodec/huffman.c index 7b33bdd7f3..42f28859c7 100644 --- a/libavcodec/huffman.c +++ b/libavcodec/huffman.c @@ -90,15 +90,14 @@ int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, cur_node = nb_codes; nodes[nb_codes*2-1].count = 0; for(i = 0; i < nb_codes*2-1; i += 2){ + uint32_t cur_count = nodes[i].count + nodes[i+1].count; nodes[cur_node].sym = HNODE; - nodes[cur_node].count = nodes[i].count + nodes[i+1].count; + nodes[cur_node].count = cur_count; nodes[cur_node].n0 = i; - for(j = cur_node; j > 0; j--){ - if(nodes[j].count > nodes[j-1].count || - (nodes[j].count == nodes[j-1].count && - (!(flags & FF_HUFFMAN_FLAG_HNODE_FIRST) || - nodes[j].n0==j-1 || nodes[j].n0==j-2 || - (nodes[j].sym!=HNODE && nodes[j-1].sym!=HNODE)))) + for(j = cur_node; j > i + 2; j--){ + if(cur_count > nodes[j-1].count || + (cur_count == nodes[j-1].count && + !(flags & FF_HUFFMAN_FLAG_HNODE_FIRST))) break; FFSWAP(Node, nodes[j], nodes[j-1]); } |