Merge branch 'master' into 0.11
[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., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, 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: Data from which the bit reader will read
35  * @size: Size of @data in bytes
36  * @byte: Current byte position
37  * @bit: Bit position in the current byte
38  *
39  * A bit reader instance.
40  */
41 typedef struct {
42   const guint8 *data;
43   guint size;
44
45   guint byte;  /* Byte position */
46   guint bit;   /* Bit position in the current byte */
47 } GstBitReader;
48
49 GstBitReader * gst_bit_reader_new (const guint8 *data, guint size);
50 void gst_bit_reader_free (GstBitReader *reader);
51
52 void gst_bit_reader_init (GstBitReader *reader, const guint8 *data, guint size);
53
54 gboolean gst_bit_reader_set_pos (GstBitReader *reader, guint pos);
55
56 guint gst_bit_reader_get_pos (const GstBitReader *reader);
57 guint gst_bit_reader_get_remaining (const GstBitReader *reader);
58
59 guint gst_bit_reader_get_size (const GstBitReader *reader);
60
61 gboolean gst_bit_reader_skip (GstBitReader *reader, guint nbits);
62 gboolean gst_bit_reader_skip_to_byte (GstBitReader *reader);
63
64 gboolean gst_bit_reader_get_bits_uint8 (GstBitReader *reader, guint8 *val, guint nbits);
65 gboolean gst_bit_reader_get_bits_uint16 (GstBitReader *reader, guint16 *val, guint nbits);
66 gboolean gst_bit_reader_get_bits_uint32 (GstBitReader *reader, guint32 *val, guint nbits);
67 gboolean gst_bit_reader_get_bits_uint64 (GstBitReader *reader, guint64 *val, guint nbits);
68
69 gboolean gst_bit_reader_peek_bits_uint8 (const GstBitReader *reader, guint8 *val, guint nbits);
70 gboolean gst_bit_reader_peek_bits_uint16 (const GstBitReader *reader, guint16 *val, guint nbits);
71 gboolean gst_bit_reader_peek_bits_uint32 (const GstBitReader *reader, guint32 *val, guint nbits);
72 gboolean gst_bit_reader_peek_bits_uint64 (const GstBitReader *reader, guint64 *val, guint nbits);
73
74 /**
75  * GST_BIT_READER_INIT:
76  * @data: Data from which the #GstBitReader should read
77  * @size: Size of @data in bytes
78  *
79  * A #GstBitReader must be initialized with this macro, before it can be
80  * used. This macro can used be to initialize a variable, but it cannot
81  * be assigned to a variable. In that case you have to use
82  * gst_bit_reader_init().
83  *
84  * Since: 0.10.22
85  */
86 #define GST_BIT_READER_INIT(data, size) {data, size, 0, 0}
87
88 /* Unchecked variants */
89
90 static inline void
91 gst_bit_reader_skip_unchecked (GstBitReader * reader, guint nbits)
92 {
93   reader->bit += nbits;
94   reader->byte += reader->bit / 8;
95   reader->bit = reader->bit % 8;
96 }
97
98 static inline void
99 gst_bit_reader_skip_to_byte_unchecked (GstBitReader * reader)
100 {
101   if (reader->bit) {
102     reader->bit = 0;
103     reader->byte++;
104   }
105 }
106
107 #define __GST_BIT_READER_READ_BITS_UNCHECKED(bits) \
108 static inline guint##bits \
109 gst_bit_reader_peek_bits_uint##bits##_unchecked (const GstBitReader *reader, guint nbits) \
110 { \
111   guint##bits ret = 0; \
112   const guint8 *data; \
113   guint byte, bit; \
114   \
115   data = reader->data; \
116   byte = reader->byte; \
117   bit = reader->bit; \
118   \
119   while (nbits > 0) { \
120     guint toread = MIN (nbits, 8 - bit); \
121     \
122     ret <<= toread; \
123     ret |= (data[byte] & (0xff >> bit)) >> (8 - toread - bit); \
124     \
125     bit += toread; \
126     if (bit >= 8) { \
127       byte++; \
128       bit = 0; \
129     } \
130     nbits -= toread; \
131   } \
132   \
133   return ret; \
134 } \
135 \
136 static inline guint##bits \
137 gst_bit_reader_get_bits_uint##bits##_unchecked (GstBitReader *reader, guint nbits) \
138 { \
139   guint##bits ret; \
140   \
141   ret = gst_bit_reader_peek_bits_uint##bits##_unchecked (reader, nbits); \
142   \
143   gst_bit_reader_skip_unchecked (reader, nbits); \
144   \
145   return ret; \
146 }
147
148 __GST_BIT_READER_READ_BITS_UNCHECKED (8)
149 __GST_BIT_READER_READ_BITS_UNCHECKED (16)
150 __GST_BIT_READER_READ_BITS_UNCHECKED (32)
151 __GST_BIT_READER_READ_BITS_UNCHECKED (64)
152
153 #undef __GST_BIT_READER_READ_BITS_UNCHECKED
154
155 /* unchecked variants -- do not use */
156
157 static inline guint
158 _gst_bit_reader_get_size_unchecked (const GstBitReader * reader)
159 {
160   return reader->size * 8;
161 }
162
163 static inline guint
164 _gst_bit_reader_get_pos_unchecked (const GstBitReader * reader)
165 {
166   return reader->byte * 8 + reader->bit;
167 }
168
169 static inline guint
170 _gst_bit_reader_get_remaining_unchecked (const GstBitReader * reader)
171 {
172   return reader->size * 8 - (reader->byte * 8 + reader->bit);
173 }
174
175 /* inlined variants -- do not use directly */
176 static inline guint
177 _gst_bit_reader_get_size_inline (const GstBitReader * reader)
178 {
179   g_return_val_if_fail (reader != NULL, 0);
180
181   return _gst_bit_reader_get_size_unchecked (reader);
182 }
183
184 static inline guint
185 _gst_bit_reader_get_pos_inline (const GstBitReader * reader)
186 {
187   g_return_val_if_fail (reader != NULL, 0);
188
189   return _gst_bit_reader_get_pos_unchecked (reader);
190 }
191
192 static inline guint
193 _gst_bit_reader_get_remaining_inline (const GstBitReader * reader)
194 {
195   g_return_val_if_fail (reader != NULL, 0);
196
197   return _gst_bit_reader_get_remaining_unchecked (reader);
198 }
199
200 static inline gboolean
201 _gst_bit_reader_skip_inline (GstBitReader * reader, guint nbits)
202 {
203   g_return_val_if_fail (reader != NULL, FALSE);
204
205   if (_gst_bit_reader_get_remaining_unchecked (reader) < nbits)
206     return FALSE;
207
208   gst_bit_reader_skip_unchecked (reader, nbits);
209
210   return TRUE;
211 }
212
213 static inline gboolean
214 _gst_bit_reader_skip_to_byte_inline (GstBitReader * reader)
215 {
216   g_return_val_if_fail (reader != NULL, FALSE);
217
218   if (reader->byte > reader->size)
219     return FALSE;
220
221   gst_bit_reader_skip_to_byte_unchecked (reader);
222
223   return TRUE;
224 }
225
226 #define __GST_BIT_READER_READ_BITS_INLINE(bits) \
227 static inline gboolean \
228 _gst_bit_reader_get_bits_uint##bits##_inline (GstBitReader *reader, guint##bits *val, guint nbits) \
229 { \
230   g_return_val_if_fail (reader != NULL, FALSE); \
231   g_return_val_if_fail (val != NULL, FALSE); \
232   g_return_val_if_fail (nbits <= bits, FALSE); \
233   \
234   if (_gst_bit_reader_get_remaining_unchecked (reader) < nbits) \
235     return FALSE; \
236 \
237   *val = gst_bit_reader_get_bits_uint##bits##_unchecked (reader, nbits); \
238   return TRUE; \
239 } \
240 \
241 static inline gboolean \
242 _gst_bit_reader_peek_bits_uint##bits##_inline (const GstBitReader *reader, guint##bits *val, guint nbits) \
243 { \
244   g_return_val_if_fail (reader != NULL, FALSE); \
245   g_return_val_if_fail (val != NULL, FALSE); \
246   g_return_val_if_fail (nbits <= bits, FALSE); \
247   \
248   if (_gst_bit_reader_get_remaining_unchecked (reader) < nbits) \
249     return FALSE; \
250 \
251   *val = gst_bit_reader_peek_bits_uint##bits##_unchecked (reader, nbits); \
252   return TRUE; \
253 }
254
255 __GST_BIT_READER_READ_BITS_INLINE (8)
256 __GST_BIT_READER_READ_BITS_INLINE (16)
257 __GST_BIT_READER_READ_BITS_INLINE (32)
258 __GST_BIT_READER_READ_BITS_INLINE (64)
259
260 #undef __GST_BIT_READER_READ_BITS_INLINE
261
262 #ifndef GST_BIT_READER_DISABLE_INLINES
263
264 #define gst_bit_reader_get_size(reader) \
265     _gst_bit_reader_get_size_inline (reader)
266 #define gst_bit_reader_get_pos(reader) \
267     _gst_bit_reader_get_pos_inline (reader)
268 #define gst_bit_reader_get_remaining(reader) \
269     _gst_bit_reader_get_remaining_inline (reader)
270
271 /* we use defines here so we can add the G_LIKELY() */
272
273 #define gst_bit_reader_skip(reader, nbits)\
274     G_LIKELY (_gst_bit_reader_skip_inline(reader, nbits))
275 #define gst_bit_reader_skip_to_byte(reader)\
276     G_LIKELY (_gst_bit_reader_skip_to_byte_inline(reader))
277
278 #define gst_bit_reader_get_bits_uint8(reader, val, nbits) \
279     G_LIKELY (_gst_bit_reader_get_bits_uint8_inline (reader, val, nbits))
280 #define gst_bit_reader_get_bits_uint16(reader, val, nbits) \
281     G_LIKELY (_gst_bit_reader_get_bits_uint16_inline (reader, val, nbits))
282 #define gst_bit_reader_get_bits_uint32(reader, val, nbits) \
283     G_LIKELY (_gst_bit_reader_get_bits_uint32_inline (reader, val, nbits))
284 #define gst_bit_reader_get_bits_uint64(reader, val, nbits) \
285     G_LIKELY (_gst_bit_reader_get_bits_uint64_inline (reader, val, nbits))
286
287 #define gst_bit_reader_peek_bits_uint8(reader, val, nbits) \
288     G_LIKELY (_gst_bit_reader_peek_bits_uint8_inline (reader, val, nbits))
289 #define gst_bit_reader_peek_bits_uint16(reader, val, nbits) \
290     G_LIKELY (_gst_bit_reader_peek_bits_uint16_inline (reader, val, nbits))
291 #define gst_bit_reader_peek_bits_uint32(reader, val, nbits) \
292     G_LIKELY (_gst_bit_reader_peek_bits_uint32_inline (reader, val, nbits))
293 #define gst_bit_reader_peek_bits_uint64(reader, val, nbits) \
294     G_LIKELY (_gst_bit_reader_peek_bits_uint64_inline (reader, val, nbits))
295 #endif
296
297 G_END_DECLS
298
299 #endif /* __GST_BIT_READER_H__ */