From 7b41cbac7fc03cfc4714049fbe849cb3f96ffaa5 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 13 Jan 2014 01:03:54 +0100 Subject: [PATCH] avcodec/huffman: extend ff_huff_gen_len_table() to allow >8bit Signed-off-by: Michael Niedermayer --- libavcodec/huffman.c | 20 +++++++++++++++----- libavcodec/huffman.h | 2 +- libavcodec/huffyuvenc.c | 5 +++-- libavcodec/utvideoenc.c | 4 +++- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/libavcodec/huffman.c b/libavcodec/huffman.c index 8dd356dde4..73d21ab650 100644 --- a/libavcodec/huffman.c +++ b/libavcodec/huffman.c @@ -52,13 +52,18 @@ static void heap_sift(HeapElem *h, int root, int size) } } -void ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats) +int ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats, int size) { - HeapElem h[256]; - int up[2*256]; - int len[2*256]; + HeapElem *h = av_malloc(sizeof(*h) * size); + int *up = av_malloc(sizeof(*up) * 2 * size); + uint8_t *len = av_malloc(sizeof(*len) * 2 * size); int offset, i, next; - int size = 256; + int ret = 0; + + if (!h || !up || !len) { + ret = AVERROR(ENOMEM); + goto end; + } for (offset = 1; ; offset <<= 1) { for (i=0; i < size; i++) { @@ -89,6 +94,11 @@ void ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats) } if (i==size) break; } +end: + av_free(h); + av_free(up); + av_free(len); + return ret; } static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, diff --git a/libavcodec/huffman.h b/libavcodec/huffman.h index cec95379ac..b1ace62201 100644 --- a/libavcodec/huffman.h +++ b/libavcodec/huffman.h @@ -43,6 +43,6 @@ typedef int (*HuffCmp)(const void *va, const void *vb); int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, int nb_bits, Node *nodes, HuffCmp cmp, int flags); -void ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats); +int ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats, int n); #endif /* AVCODEC_HUFFMAN_H */ diff --git a/libavcodec/huffyuvenc.c b/libavcodec/huffyuvenc.c index 36dfecd5fb..0ab61b26c0 100644 --- a/libavcodec/huffyuvenc.c +++ b/libavcodec/huffyuvenc.c @@ -144,7 +144,7 @@ static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf) static int store_huffman_tables(HYuvContext *s, uint8_t *buf) { - int i; + int i, ret; int size = 0; int count = 3; @@ -152,7 +152,8 @@ static int store_huffman_tables(HYuvContext *s, uint8_t *buf) count = 1 + s->alpha + 2*s->chroma; for (i = 0; i < count; i++) { - ff_huff_gen_len_table(s->len[i], s->stats[i]); + if ((ret = ff_huff_gen_len_table(s->len[i], s->stats[i], 256)) < 0) + return ret; if (ff_huffyuv_generate_bits_table(s->bits[i], s->len[i]) < 0) { return -1; diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c index e5a858d5ae..f6e4e7e358 100644 --- a/libavcodec/utvideoenc.c +++ b/libavcodec/utvideoenc.c @@ -363,6 +363,7 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src, uint32_t offset = 0, slice_len = 0; int i, sstart, send = 0; int symbol; + int ret; /* Do prediction / make planes */ switch (c->frame_pred) { @@ -429,7 +430,8 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src, } /* Calculate huffman lengths */ - ff_huff_gen_len_table(lengths, counts); + if ((ret = ff_huff_gen_len_table(lengths, counts, 256)) < 0) + return ret; /* * Write the plane's header into the output packet: