• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #define GST_BIT_READER_DISABLE_INLINES
26 #include "gstbitreader.h"
27 
28 #include <string.h>
29 
30 /**
31  * SECTION:gstbitreader
32  * @title: GstBitReader
33  * @short_description: Reads any number of bits from a memory buffer
34  * @symbols:
35  * - gst_bit_reader_skip_unchecked
36  * - gst_bit_reader_skip_to_byte_unchecked
37  * - gst_bit_reader_get_bits_uint8_unchecked
38  * - gst_bit_reader_peek_bits_uint8_unchecked
39  * - gst_bit_reader_get_bits_uint16_unchecked
40  * - gst_bit_reader_peek_bits_uint16_unchecked
41  * - gst_bit_reader_get_bits_uint32_unchecked
42  * - gst_bit_reader_peek_bits_uint32_unchecked
43  * - gst_bit_reader_get_bits_uint64_unchecked
44  * - gst_bit_reader_peek_bits_uint64_unchecked
45  *
46  * #GstBitReader provides a bit reader that can read any number of bits
47  * from a memory buffer. It provides functions for reading any number of bits
48  * into 8, 16, 32 and 64 bit variables.
49  */
50 
51 /**
52  * gst_bit_reader_new: (skip)
53  * @data: (array length=size): Data from which the #GstBitReader
54  *   should read
55  * @size: Size of @data in bytes
56  *
57  * Create a new #GstBitReader instance, which will read from @data.
58  *
59  * Free-function: gst_bit_reader_free
60  *
61  * Returns: (transfer full): a new #GstBitReader instance
62  */
63 GstBitReader *
gst_bit_reader_new(const guint8 * data,guint size)64 gst_bit_reader_new (const guint8 * data, guint size)
65 {
66   GstBitReader *ret = g_slice_new0 (GstBitReader);
67 
68   ret->data = data;
69   ret->size = size;
70 
71   return ret;
72 }
73 
74 /**
75  * gst_bit_reader_free:
76  * @reader: (in) (transfer full): a #GstBitReader instance
77  *
78  * Frees a #GstBitReader instance, which was previously allocated by
79  * gst_bit_reader_new().
80  */
81 void
gst_bit_reader_free(GstBitReader * reader)82 gst_bit_reader_free (GstBitReader * reader)
83 {
84   g_return_if_fail (reader != NULL);
85 
86   g_slice_free (GstBitReader, reader);
87 }
88 
89 /**
90  * gst_bit_reader_init:
91  * @reader: a #GstBitReader instance
92  * @data: (in) (array length=size): data from which the bit reader should read
93  * @size: Size of @data in bytes
94  *
95  * Initializes a #GstBitReader instance to read from @data. This function
96  * can be called on already initialized instances.
97  */
98 void
gst_bit_reader_init(GstBitReader * reader,const guint8 * data,guint size)99 gst_bit_reader_init (GstBitReader * reader, const guint8 * data, guint size)
100 {
101   g_return_if_fail (reader != NULL);
102 
103   reader->data = data;
104   reader->size = size;
105   reader->byte = reader->bit = 0;
106 }
107 
108 /**
109  * gst_bit_reader_set_pos:
110  * @reader: a #GstBitReader instance
111  * @pos: The new position in bits
112  *
113  * Sets the new position of a #GstBitReader instance to @pos in bits.
114  *
115  * Returns: %TRUE if the position could be set successfully, %FALSE
116  * otherwise.
117  */
118 gboolean
gst_bit_reader_set_pos(GstBitReader * reader,guint pos)119 gst_bit_reader_set_pos (GstBitReader * reader, guint pos)
120 {
121   g_return_val_if_fail (reader != NULL, FALSE);
122 
123   if (pos > reader->size * 8)
124     return FALSE;
125 
126   reader->byte = pos / 8;
127   reader->bit = pos % 8;
128 
129   return TRUE;
130 }
131 
132 /**
133  * gst_bit_reader_get_pos:
134  * @reader: a #GstBitReader instance
135  *
136  * Returns the current position of a #GstBitReader instance in bits.
137  *
138  * Returns: The current position of @reader in bits.
139  */
140 guint
gst_bit_reader_get_pos(const GstBitReader * reader)141 gst_bit_reader_get_pos (const GstBitReader * reader)
142 {
143   return _gst_bit_reader_get_pos_inline (reader);
144 }
145 
146 /**
147  * gst_bit_reader_get_remaining:
148  * @reader: a #GstBitReader instance
149  *
150  * Returns the remaining number of bits of a #GstBitReader instance.
151  *
152  * Returns: The remaining number of bits of @reader instance.
153  */
154 guint
gst_bit_reader_get_remaining(const GstBitReader * reader)155 gst_bit_reader_get_remaining (const GstBitReader * reader)
156 {
157   return _gst_bit_reader_get_remaining_inline (reader);
158 }
159 
160 /**
161  * gst_bit_reader_get_size:
162  * @reader: a #GstBitReader instance
163  *
164  * Returns the total number of bits of a #GstBitReader instance.
165  *
166  * Returns: The total number of bits of @reader instance.
167  */
168 guint
gst_bit_reader_get_size(const GstBitReader * reader)169 gst_bit_reader_get_size (const GstBitReader * reader)
170 {
171   return _gst_bit_reader_get_size_inline (reader);
172 }
173 
174 /**
175  * gst_bit_reader_skip:
176  * @reader: a #GstBitReader instance
177  * @nbits: the number of bits to skip
178  *
179  * Skips @nbits bits of the #GstBitReader instance.
180  *
181  * Returns: %TRUE if @nbits bits could be skipped, %FALSE otherwise.
182  */
183 gboolean
gst_bit_reader_skip(GstBitReader * reader,guint nbits)184 gst_bit_reader_skip (GstBitReader * reader, guint nbits)
185 {
186   return _gst_bit_reader_skip_inline (reader, nbits);
187 }
188 
189 /**
190  * gst_bit_reader_skip_to_byte:
191  * @reader: a #GstBitReader instance
192  *
193  * Skips until the next byte.
194  *
195  * Returns: %TRUE if successful, %FALSE otherwise.
196  */
197 gboolean
gst_bit_reader_skip_to_byte(GstBitReader * reader)198 gst_bit_reader_skip_to_byte (GstBitReader * reader)
199 {
200   return _gst_bit_reader_skip_to_byte_inline (reader);
201 }
202 
203 /**
204  * gst_bit_reader_get_bits_uint8:
205  * @reader: a #GstBitReader instance
206  * @val: (out): Pointer to a #guint8 to store the result
207  * @nbits: number of bits to read
208  *
209  * Read @nbits bits into @val and update the current position.
210  *
211  * Returns: %TRUE if successful, %FALSE otherwise.
212  */
213 
214 /**
215  * gst_bit_reader_get_bits_uint16:
216  * @reader: a #GstBitReader instance
217  * @val: (out): Pointer to a #guint16 to store the result
218  * @nbits: number of bits to read
219  *
220  * Read @nbits bits into @val and update the current position.
221  *
222  * Returns: %TRUE if successful, %FALSE otherwise.
223  */
224 
225 /**
226  * gst_bit_reader_get_bits_uint32:
227  * @reader: a #GstBitReader instance
228  * @val: (out): Pointer to a #guint32 to store the result
229  * @nbits: number of bits to read
230  *
231  * Read @nbits bits into @val and update the current position.
232  *
233  * Returns: %TRUE if successful, %FALSE otherwise.
234  */
235 
236 /**
237  * gst_bit_reader_get_bits_uint64:
238  * @reader: a #GstBitReader instance
239  * @val: (out): Pointer to a #guint64 to store the result
240  * @nbits: number of bits to read
241  *
242  * Read @nbits bits into @val and update the current position.
243  *
244  * Returns: %TRUE if successful, %FALSE otherwise.
245  */
246 
247 /**
248  * gst_bit_reader_peek_bits_uint8:
249  * @reader: a #GstBitReader instance
250  * @val: (out): Pointer to a #guint8 to store the result
251  * @nbits: number of bits to read
252  *
253  * Read @nbits bits into @val but keep the current position.
254  *
255  * Returns: %TRUE if successful, %FALSE otherwise.
256  */
257 
258 /**
259  * gst_bit_reader_peek_bits_uint16:
260  * @reader: a #GstBitReader instance
261  * @val: (out): Pointer to a #guint16 to store the result
262  * @nbits: number of bits to read
263  *
264  * Read @nbits bits into @val but keep the current position.
265  *
266  * Returns: %TRUE if successful, %FALSE otherwise.
267  */
268 
269 /**
270  * gst_bit_reader_peek_bits_uint32:
271  * @reader: a #GstBitReader instance
272  * @val: (out): Pointer to a #guint32 to store the result
273  * @nbits: number of bits to read
274  *
275  * Read @nbits bits into @val but keep the current position.
276  *
277  * Returns: %TRUE if successful, %FALSE otherwise.
278  */
279 
280 /**
281  * gst_bit_reader_peek_bits_uint64:
282  * @reader: a #GstBitReader instance
283  * @val: (out): Pointer to a #guint64 to store the result
284  * @nbits: number of bits to read
285  *
286  * Read @nbits bits into @val but keep the current position.
287  *
288  * Returns: %TRUE if successful, %FALSE otherwise.
289  */
290 
291 #define GST_BIT_READER_READ_BITS(bits) \
292 gboolean \
293 gst_bit_reader_peek_bits_uint##bits (const GstBitReader *reader, guint##bits *val, guint nbits) \
294 { \
295   return _gst_bit_reader_peek_bits_uint##bits##_inline (reader, val, nbits); \
296 } \
297 \
298 gboolean \
299 gst_bit_reader_get_bits_uint##bits (GstBitReader *reader, guint##bits *val, guint nbits) \
300 { \
301   return _gst_bit_reader_get_bits_uint##bits##_inline (reader, val, nbits); \
302 }
303 
304 GST_BIT_READER_READ_BITS (8);
305 GST_BIT_READER_READ_BITS (16);
306 GST_BIT_READER_READ_BITS (32);
307 GST_BIT_READER_READ_BITS (64);
308