Add few missing allow-none annotation
[platform/upstream/gstreamer.git] / libs / gst / base / gstbitreader.h
1 /* GStreamer
2  *
3  * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #ifndef __GST_BIT_READER_H__
22 #define __GST_BIT_READER_H__
23
24 #include <gst/gst.h>
25
26 /* FIXME: inline functions */
27
28 G_BEGIN_DECLS
29
30 #define GST_BIT_READER(reader) ((GstBitReader *) (reader))
31
32 /**
33  * GstBitReader:
34  * @data: (array length=size): Data from which the bit reader will
35  *   read
36  * @size: Size of @data in bytes
37  * @byte: Current byte position
38  * @bit: Bit position in the current byte
39  *
40  * A bit reader instance.
41  */
42 typedef struct {
43   const guint8 *data;
44   guint size;
45
46   guint byte;  /* Byte position */
47   guint bit;   /* Bit position in the current byte */
48
49   /* < private > */
50   gpointer _gst_reserved[GST_PADDING];
51 } GstBitReader;
52
53 GstBitReader *  gst_bit_reader_new              (const guint8 *data, guint size) G_GNUC_MALLOC;
54 void            gst_bit_reader_free             (GstBitReader *reader);
55
56 void            gst_bit_reader_init             (GstBitReader *reader, const guint8 *data, guint size);
57
58 gboolean        gst_bit_reader_set_pos          (GstBitReader *reader, guint pos);
59 guint           gst_bit_reader_get_pos          (const GstBitReader *reader);
60
61 guint           gst_bit_reader_get_remaining    (const GstBitReader *reader);
62
63 guint           gst_bit_reader_get_size         (const GstBitReader *reader);
64
65 gboolean        gst_bit_reader_skip             (GstBitReader *reader, guint nbits);
66 gboolean        gst_bit_reader_skip_to_byte     (GstBitReader *reader);
67
68 gboolean        gst_bit_reader_get_bits_uint8   (GstBitReader *reader, guint8 *val, guint nbits);
69 gboolean        gst_bit_reader_get_bits_uint16  (GstBitReader *reader, guint16 *val, guint nbits);
70 gboolean        gst_bit_reader_get_bits_uint32  (GstBitReader *reader, guint32 *val, guint nbits);
71 gboolean        gst_bit_reader_get_bits_uint64  (GstBitReader *reader, guint64 *val, guint nbits);
72
73 gboolean        gst_bit_reader_peek_bits_uint8  (const GstBitReader *reader, guint8 *val, guint nbits);
74 gboolean        gst_bit_reader_peek_bits_uint16 (const GstBitReader *reader, guint16 *val, guint nbits);
75 gboolean        gst_bit_reader_peek_bits_uint32 (const GstBitReader *reader, guint32 *val, guint nbits);
76 gboolean        gst_bit_reader_peek_bits_uint64 (const GstBitReader *reader, guint64 *val, guint nbits);
77
78 /**
79  * GST_BIT_READER_INIT:
80  * @data: Data from which the #GstBitReader should read
81  * @size: Size of @data in bytes
82  *
83  * A #GstBitReader must be initialized with this macro, before it can be
84  * used. This macro can used be to initialize a variable, but it cannot
85  * be assigned to a variable. In that case you have to use
86  * gst_bit_reader_init().
87  */
88 #define GST_BIT_READER_INIT(data, size) {data, size, 0, 0}
89
90 /* Unchecked variants */
91
92 static inline void
93 gst_bit_reader_skip_unchecked (GstBitReader * reader, guint nbits)
94 {
95   reader->bit += nbits;
96   reader->byte += reader->bit / 8;
97   reader->bit = reader->bit % 8;
98 }
99
100 static inline void
101 gst_bit_reader_skip_to_byte_unchecked (GstBitReader * reader)
102 {
103   if (reader->bit) {
104     reader->bit = 0;
105     reader->byte++;
106   }
107 }
108
109 #define __GST_BIT_READER_READ_BITS_UNCHECKED(bits) \
110 static inline guint##bits \
111 gst_bit_reader_peek_bits_uint##bits##_unchecked (const GstBitReader *reader, guint nbits) \
112 { \
113   guint##bits ret = 0; \
114   const guint8 *data; \
115   guint byte, bit; \
116   \
117   data = reader->data; \
118   byte = reader->byte; \
119   bit = reader->bit; \
120   \
121   while (nbits > 0) { \
122     guint toread = MIN (nbits, 8 - bit); \
123     \
124     ret <<= toread; \
125     ret |= (data[byte] & (0xff >> bit)) >> (8 - toread - bit); \
126     \
127     bit += toread; \
128     if (bit >= 8) { \
129       byte++; \
130       bit = 0; \
131     } \
132     nbits -= toread; \
133   } \
134   \
135   return ret; \
136 } \
137 \
138 static inline guint##bits \
139 gst_bit_reader_get_bits_uint##bits##_unchecked (GstBitReader *reader, guint nbits) \
140 { \
141   guint##bits ret; \
142   \
143   ret = gst_bit_reader_peek_bits_uint##bits##_unchecked (reader, nbits); \
144   \
145   gst_bit_reader_skip_unchecked (reader, nbits); \
146   \
147   return ret; \
148 }
149
150 __GST_BIT_READER_READ_BITS_UNCHECKED (8)
151 __GST_BIT_READER_READ_BITS_UNCHECKED (16)
152 __GST_BIT_READER_READ_BITS_UNCHECKED (32)
153 __GST_BIT_READER_READ_BITS_UNCHECKED (64)
154
155 #undef __GST_BIT_READER_READ_BITS_UNCHECKED
156
157 /* unchecked variants -- do not use */
158
159 static inline guint
160 _gst_bit_reader_get_size_unchecked (const GstBitReader * reader)
161 {
162   return reader->size * 8;
163 }
164
165 static inline guint
166 _gst_bit_reader_get_pos_unchecked (const GstBitReader * reader)
167 {
168   return reader->byte * 8 + reader->bit;
169 }
170
171 static inline guint
172 _gst_bit_reader_get_remaining_unchecked (const GstBitReader * reader)
173 {
174   return reader->size * 8 - (reader->byte * 8 + reader->bit);
175 }
176
177 /* inlined variants -- do not use directly */
178 static inline guint
179 _gst_bit_reader_get_size_inline (const GstBitReader * reader)
180 {
181   g_return_val_if_fail (reader != NULL, 0);
182
183   return _gst_bit_reader_get_size_unchecked (reader);
184 }
185
186 static inline guint
187 _gst_bit_reader_get_pos_inline (const GstBitReader * reader)
188 {
189   g_return_val_if_fail (reader != NULL, 0);
190
191   return _gst_bit_reader_get_pos_unchecked (reader);
192 }
193
194 static inline guint
195 _gst_bit_reader_get_remaining_inline (const GstBitReader * reader)
196 {
197   g_return_val_if_fail (reader != NULL, 0);
198
199   return _gst_bit_reader_get_remaining_unchecked (reader);
200 }
201
202 static inline gboolean
203 _gst_bit_reader_skip_inline (GstBitReader * reader, guint nbits)
204 {
205   g_return_val_if_fail (reader != NULL, FALSE);
206
207   if (_gst_bit_reader_get_remaining_unchecked (reader) < nbits)
208     return FALSE;
209
210   gst_bit_reader_skip_unchecked (reader, nbits);
211
212   return TRUE;
213 }
214
215 static inline gboolean
216 _gst_bit_reader_skip_to_byte_inline (GstBitReader * reader)
217 {
218   g_return_val_if_fail (reader != NULL, FALSE);
219
220   if (reader->byte > reader->size)
221     return FALSE;
222
223   gst_bit_reader_skip_to_byte_unchecked (reader);
224
225   return TRUE;
226 }
227
228 #define __GST_BIT_READER_READ_BITS_INLINE(bits) \
229 static inline gboolean \
230 _gst_bit_reader_get_bits_uint##bits##_inline (GstBitReader *reader, guint##bits *val, guint nbits) \
231 { \
232   g_return_val_if_fail (reader != NULL, FALSE); \
233   g_return_val_if_fail (val != NULL, FALSE); \
234   g_return_val_if_fail (nbits <= bits, FALSE); \
235   \
236   if (_gst_bit_reader_get_remaining_unchecked (reader) < nbits) \
237     return FALSE; \
238 \
239   *val = gst_bit_reader_get_bits_uint##bits##_unchecked (reader, nbits); \
240   return TRUE; \
241 } \
242 \
243 static inline gboolean \
244 _gst_bit_reader_peek_bits_uint##bits##_inline (const GstBitReader *reader, guint##bits *val, guint nbits) \
245 { \
246   g_return_val_if_fail (reader != NULL, FALSE); \
247   g_return_val_if_fail (val != NULL, FALSE); \
248   g_return_val_if_fail (nbits <= bits, FALSE); \
249   \
250   if (_gst_bit_reader_get_remaining_unchecked (reader) < nbits) \
251     return FALSE; \
252 \
253   *val = gst_bit_reader_peek_bits_uint##bits##_unchecked (reader, nbits); \
254   return TRUE; \
255 }
256
257 __GST_BIT_READER_READ_BITS_INLINE (8)
258 __GST_BIT_READER_READ_BITS_INLINE (16)
259 __GST_BIT_READER_READ_BITS_INLINE (32)
260 __GST_BIT_READER_READ_BITS_INLINE (64)
261
262 #undef __GST_BIT_READER_READ_BITS_INLINE
263
264 #ifndef GST_BIT_READER_DISABLE_INLINES
265
266 #define gst_bit_reader_get_size(reader) \
267     _gst_bit_reader_get_size_inline (reader)
268 #define gst_bit_reader_get_pos(reader) \
269     _gst_bit_reader_get_pos_inline (reader)
270 #define gst_bit_reader_get_remaining(reader) \
271     _gst_bit_reader_get_remaining_inline (reader)
272
273 /* we use defines here so we can add the G_LIKELY() */
274
275 #define gst_bit_reader_skip(reader, nbits)\
276     G_LIKELY (_gst_bit_reader_skip_inline(reader, nbits))
277 #define gst_bit_reader_skip_to_byte(reader)\
278     G_LIKELY (_gst_bit_reader_skip_to_byte_inline(reader))
279
280 #define gst_bit_reader_get_bits_uint8(reader, val, nbits) \
281     G_LIKELY (_gst_bit_reader_get_bits_uint8_inline (reader, val, nbits))
282 #define gst_bit_reader_get_bits_uint16(reader, val, nbits) \
283     G_LIKELY (_gst_bit_reader_get_bits_uint16_inline (reader, val, nbits))
284 #define gst_bit_reader_get_bits_uint32(reader, val, nbits) \
285     G_LIKELY (_gst_bit_reader_get_bits_uint32_inline (reader, val, nbits))
286 #define gst_bit_reader_get_bits_uint64(reader, val, nbits) \
287     G_LIKELY (_gst_bit_reader_get_bits_uint64_inline (reader, val, nbits))
288
289 #define gst_bit_reader_peek_bits_uint8(reader, val, nbits) \
290     G_LIKELY (_gst_bit_reader_peek_bits_uint8_inline (reader, val, nbits))
291 #define gst_bit_reader_peek_bits_uint16(reader, val, nbits) \
292     G_LIKELY (_gst_bit_reader_peek_bits_uint16_inline (reader, val, nbits))
293 #define gst_bit_reader_peek_bits_uint32(reader, val, nbits) \
294     G_LIKELY (_gst_bit_reader_peek_bits_uint32_inline (reader, val, nbits))
295 #define gst_bit_reader_peek_bits_uint64(reader, val, nbits) \
296     G_LIKELY (_gst_bit_reader_peek_bits_uint64_inline (reader, val, nbits))
297 #endif
298
299 G_END_DECLS
300
301 #endif /* __GST_BIT_READER_H__ */