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