Browse code

avcodec/huffman: extend ff_huff_gen_len_table() to allow >8bit

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2014/01/13 09:03:54
Showing 4 changed files
... ...
@@ -52,13 +52,18 @@ static void heap_sift(HeapElem *h, int root, int size)
52 52
     }
53 53
 }
54 54
 
55
-void ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats)
55
+int ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats, int size)
56 56
 {
57
-    HeapElem h[256];
58
-    int up[2*256];
59
-    int len[2*256];
57
+    HeapElem *h  = av_malloc(sizeof(*h) * size);
58
+    int *up      = av_malloc(sizeof(*up) * 2 * size);
59
+    uint8_t *len = av_malloc(sizeof(*len) * 2 * size);
60 60
     int offset, i, next;
61
-    int size = 256;
61
+    int ret = 0;
62
+
63
+    if (!h || !up || !len) {
64
+        ret = AVERROR(ENOMEM);
65
+        goto end;
66
+    }
62 67
 
63 68
     for (offset = 1; ; offset <<= 1) {
64 69
         for (i=0; i < size; i++) {
... ...
@@ -89,6 +94,11 @@ void ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats)
89 89
         }
90 90
         if (i==size) break;
91 91
     }
92
+end:
93
+    av_free(h);
94
+    av_free(up);
95
+    av_free(len);
96
+    return ret;
92 97
 }
93 98
 
94 99
 static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat,
... ...
@@ -43,6 +43,6 @@ typedef int (*HuffCmp)(const void *va, const void *vb);
43 43
 int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes, int nb_bits,
44 44
                        Node *nodes, HuffCmp cmp, int flags);
45 45
 
46
-void ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats);
46
+int ff_huff_gen_len_table(uint8_t *dst, const uint64_t *stats, int n);
47 47
 
48 48
 #endif /* AVCODEC_HUFFMAN_H */
... ...
@@ -144,7 +144,7 @@ static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf)
144 144
 
145 145
 static int store_huffman_tables(HYuvContext *s, uint8_t *buf)
146 146
 {
147
-    int i;
147
+    int i, ret;
148 148
     int size = 0;
149 149
     int count = 3;
150 150
 
... ...
@@ -152,7 +152,8 @@ static int store_huffman_tables(HYuvContext *s, uint8_t *buf)
152 152
         count = 1 + s->alpha + 2*s->chroma;
153 153
 
154 154
     for (i = 0; i < count; i++) {
155
-        ff_huff_gen_len_table(s->len[i], s->stats[i]);
155
+        if ((ret = ff_huff_gen_len_table(s->len[i], s->stats[i], 256)) < 0)
156
+            return ret;
156 157
 
157 158
         if (ff_huffyuv_generate_bits_table(s->bits[i], s->len[i]) < 0) {
158 159
             return -1;
... ...
@@ -363,6 +363,7 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src,
363 363
     uint32_t offset = 0, slice_len = 0;
364 364
     int      i, sstart, send = 0;
365 365
     int      symbol;
366
+    int      ret;
366 367
 
367 368
     /* Do prediction / make planes */
368 369
     switch (c->frame_pred) {
... ...
@@ -429,7 +430,8 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src,
429 429
     }
430 430
 
431 431
     /* Calculate huffman lengths */
432
-    ff_huff_gen_len_table(lengths, counts);
432
+    if ((ret = ff_huff_gen_len_table(lengths, counts, 256)) < 0)
433
+        return ret;
433 434
 
434 435
     /*
435 436
      * Write the plane's header into the output packet: