]> git.sesse.net Git - ffmpeg/blob - libavcodec/vlc.h
dvbsubdec: Free subrect memory on allocation error
[ffmpeg] / libavcodec / vlc.h
1 /*
2  * This file is part of Libav.
3  *
4  * Libav is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * Libav is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with Libav; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #ifndef AVCODEC_VLC_H
20 #define AVCODEC_VLC_H
21
22 #include <stdint.h>
23
24 #include "bitstream.h"
25
26 #define VLC_TYPE int16_t
27
28 typedef struct VLC {
29     int bits;
30     VLC_TYPE (*table)[2]; ///< code, bits
31     int table_size, table_allocated;
32 } VLC;
33
34 typedef struct RL_VLC_ELEM {
35     int16_t level;
36     int8_t len;
37     uint8_t run;
38 } RL_VLC_ELEM;
39
40 #define init_vlc(vlc, nb_bits, nb_codes,                \
41                  bits, bits_wrap, bits_size,            \
42                  codes, codes_wrap, codes_size,         \
43                  flags)                                 \
44     ff_init_vlc_sparse(vlc, nb_bits, nb_codes,          \
45                        bits, bits_wrap, bits_size,      \
46                        codes, codes_wrap, codes_size,   \
47                        NULL, 0, 0, flags)
48
49 int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
50                        const void *bits, int bits_wrap, int bits_size,
51                        const void *codes, int codes_wrap, int codes_size,
52                        const void *symbols, int symbols_wrap, int symbols_size,
53                        int flags);
54 void ff_free_vlc(VLC *vlc);
55
56 #define INIT_VLC_LE             2
57 #define INIT_VLC_USE_NEW_STATIC 4
58
59 #define INIT_VLC_STATIC(vlc, bits, a, b, c, d, e, f, g, static_size)       \
60     do {                                                                   \
61         static VLC_TYPE table[static_size][2];                             \
62         (vlc)->table           = table;                                    \
63         (vlc)->table_allocated = static_size;                              \
64         init_vlc(vlc, bits, a, b, c, d, e, f, g, INIT_VLC_USE_NEW_STATIC); \
65     } while (0)
66
67 /* Return the LUT element for the given bitstream configuration. */
68 static inline int set_idx(BitstreamContext *bc, int code, int *n, int *nb_bits,
69                           VLC_TYPE (*table)[2])
70 {
71     unsigned idx;
72
73     *nb_bits = -*n;
74     idx = bitstream_peek(bc, *nb_bits) + code;
75     *n = table[idx][1];
76
77     return table[idx][0];
78 }
79
80 /**
81  * Parse a VLC code.
82  * @param bits      is the number of bits which will be read at once, must be
83  *                  identical to nb_bits in init_vlc()
84  * @param max_depth is the number of times bits bits must be read to completely
85  *                  read the longest VLC code
86  *                  = (max_vlc_length + bits - 1) / bits
87  * If the VLC code is invalid and max_depth = 1, then no bits will be removed.
88  * If the VLC code is invalid and max_depth > 1, then the number of bits removed
89  * is undefined. */
90 static inline int bitstream_read_vlc(BitstreamContext *bc, VLC_TYPE (*table)[2],
91                                      int bits, int max_depth)
92 {
93     int nb_bits;
94     unsigned idx = bitstream_peek(bc, bits);
95     int code = table[idx][0];
96     int n    = table[idx][1];
97
98     if (max_depth > 1 && n < 0) {
99         skip_remaining(bc, bits);
100         code = set_idx(bc, code, &n, &nb_bits, table);
101         if (max_depth > 2 && n < 0) {
102             skip_remaining(bc, nb_bits);
103             code = set_idx(bc, code, &n, &nb_bits, table);
104         }
105     }
106     skip_remaining(bc, n);
107
108     return code;
109 }
110
111 #define BITSTREAM_RL_VLC(level, run, bc, table, bits, max_depth) \
112     do {                                                         \
113         int n, nb_bits;                                          \
114         unsigned index = bitstream_peek(bc, bits);               \
115         level = table[index].level;                              \
116         n     = table[index].len;                                \
117                                                                  \
118         if (max_depth > 1 && n < 0) {                            \
119             bitstream_skip(bc, bits);                            \
120                                                                  \
121             nb_bits = -n;                                        \
122                                                                  \
123             index = bitstream_peek(bc, nb_bits) + level;         \
124             level = table[index].level;                          \
125             n     = table[index].len;                            \
126             if (max_depth > 2 && n < 0) {                        \
127                 bitstream_skip(bc, nb_bits);                     \
128                 nb_bits = -n;                                    \
129                                                                  \
130                 index = bitstream_peek(bc, nb_bits) + level;     \
131                 level = table[index].level;                      \
132                 n     = table[index].len;                        \
133             }                                                    \
134         }                                                        \
135         run = table[index].run;                                  \
136         bitstream_skip(bc, n);                                   \
137     } while (0)
138
139 #endif /* AVCODEC_VLC_H */