huffman/huffyuv: move lorens huffman table generation code to huffman.c/h
Reviewed-by: Derek Buitenhuis <derek.buitenhuis@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Konstantin Shishkov
|
||||
* Copyright (c) 2007 Loren Merritt
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
@@ -111,3 +112,60 @@ int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint64_t val;
|
||||
int name;
|
||||
} HeapElem;
|
||||
|
||||
static void heap_sift(HeapElem *h, int root, int size)
|
||||
{
|
||||
while(root*2+1 < size) {
|
||||
int child = root*2+1;
|
||||
if(child < size-1 && h[child].val > h[child+1].val)
|
||||
child++;
|
||||
if(h[root].val > h[child].val) {
|
||||
FFSWAP(HeapElem, h[root], h[child]);
|
||||
root = child;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ff_generate_len_table(uint8_t *dst, const uint64_t *stats){
|
||||
HeapElem h[256];
|
||||
int up[2*256];
|
||||
int len[2*256];
|
||||
int offset, i, next;
|
||||
int size = 256;
|
||||
|
||||
for(offset=1; ; offset<<=1){
|
||||
for(i=0; i<size; i++){
|
||||
h[i].name = i;
|
||||
h[i].val = (stats[i] << 8) + offset;
|
||||
}
|
||||
for(i=size/2-1; i>=0; i--)
|
||||
heap_sift(h, i, size);
|
||||
|
||||
for(next=size; next<size*2-1; next++){
|
||||
// merge the two smallest entries, and put it back in the heap
|
||||
uint64_t min1v = h[0].val;
|
||||
up[h[0].name] = next;
|
||||
h[0].val = INT64_MAX;
|
||||
heap_sift(h, 0, size);
|
||||
up[h[0].name] = next;
|
||||
h[0].name = next;
|
||||
h[0].val += min1v;
|
||||
heap_sift(h, 0, size);
|
||||
}
|
||||
|
||||
len[2*size-2] = 0;
|
||||
for(i=2*size-3; i>=size; i--)
|
||||
len[i] = len[up[i]] + 1;
|
||||
for(i=0; i<size; i++) {
|
||||
dst[i] = len[up[i]] + 1;
|
||||
if(dst[i] >= 32) break;
|
||||
}
|
||||
if(i==size) break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user