Add bit reader and byte reader classes, including documentation and an extensive...
[platform/upstream/gstreamer.git] / libs / gst / base / gstbitreader.c
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 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "gstbitreader.h"
26
27 #include <string.h>
28
29 /**
30  * SECTION:gstbitreader
31  * @short_description: Reads any number of bits from a memory buffer
32  *
33  * #GstBitReader provides a bit reader that can read any number of bits
34  * from a memory buffer. It provides functions for reading any number of bits
35  * into 8, 16, 32 and 64 bit variables.
36  */
37
38 /**
39  * gst_bit_reader_new:
40  * @data: Data from which the #GstBitReader should read
41  * @size: Size of @data in bytes
42  *
43  * Create a new #GstBitReader instance, which will read from @data.
44  *
45  * Returns: a new #GstBitReader instance
46  *
47  * Since: 0.10.22
48  */
49 GstBitReader *
50 gst_bit_reader_new (const guint8 * data, guint size)
51 {
52   GstBitReader *ret = g_slice_new0 (GstBitReader);
53
54   ret->data = data;
55   ret->size = size;
56
57   return ret;
58 }
59
60 /**
61  * gst_bit_reader_new_from_buffer:
62  * @buffer: Buffer from which the #GstBitReader should read
63  *
64  * Create a new #GstBitReader instance, which will read from the
65  * #GstBuffer @buffer.
66  *
67  * Returns: a new #GstBitReader instance
68  *
69  * Since: 0.10.22
70  */
71 GstBitReader *
72 gst_bit_reader_new_from_buffer (const GstBuffer * buffer)
73 {
74   g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
75
76   return gst_bit_reader_new (GST_BUFFER_DATA (buffer),
77       GST_BUFFER_SIZE (buffer));
78 }
79
80 /**
81  * gst_bit_reader_free:
82  * @reader: a #GstBitReader instance
83  *
84  * Frees a #GstBitReader instance, which was previously allocated by
85  * gst_bit_reader_new() or gst_bit_reader_new_from_buffer().
86  * 
87  * Since: 0.10.22
88  */
89 void
90 gst_bit_reader_free (GstBitReader * reader)
91 {
92   g_return_if_fail (reader != NULL);
93
94   g_slice_free (GstBitReader, reader);
95 }
96
97 /**
98  * gst_bit_reader_init:
99  * @reader: a #GstBitReader instance
100  * @data: Data from which the #GstBitReader should read
101  * @size: Size of @data in bytes
102  *
103  * Initializes a #GstBitReader instance to read from @data. This function
104  * can be called on already initialized instances.
105  * 
106  * Since: 0.10.22
107  */
108 void
109 gst_bit_reader_init (GstBitReader * reader, const guint8 * data, guint size)
110 {
111   g_return_if_fail (reader != NULL);
112
113   reader->data = data;
114   reader->size = size;
115   reader->byte = reader->bit = 0;
116 }
117
118 /**
119  * gst_bit_reader_init:
120  * @reader: a #GstBitReader instance
121  * @buffer: Buffer from which the #GstBitReader should read
122  *
123  * Initializes a #GstBitReader instance to read from @buffer. This function
124  * can be called on already initialized instances.
125  * 
126  * Since: 0.10.22
127  */
128 void
129 gst_bit_reader_init_from_buffer (GstBitReader * reader,
130     const GstBuffer * buffer)
131 {
132   g_return_if_fail (GST_IS_BUFFER (buffer));
133
134   gst_bit_reader_init (reader, GST_BUFFER_DATA (buffer),
135       GST_BUFFER_SIZE (buffer));
136 }
137
138 /**
139  * gst_bit_reader_set_pos:
140  * @reader: a #GstBitReader instance
141  * @pos: The new position in bits
142  *
143  * Sets the new position of a #GstBitReader instance to @pos in bits.
144  *
145  * Returns: %TRUE if the position could be set successfully, %FALSE
146  * otherwise.
147  * 
148  * Since: 0.10.22
149  */
150 gboolean
151 gst_bit_reader_set_pos (GstBitReader * reader, guint pos)
152 {
153   g_return_val_if_fail (reader != NULL, FALSE);
154
155   if (pos > reader->size * 8)
156     return FALSE;
157
158   reader->byte = pos / 8;
159   reader->bit = pos % 8;
160
161   return TRUE;
162 }
163
164 /**
165  * gst_bit_reader_get_pos:
166  * @reader: a #GstBitReader instance
167  *
168  * Returns the current position of a #GstBitReader instance in bits.
169  *
170  * Returns: The current position of @reader in bits.
171  * 
172  * Since: 0.10.22
173  */
174 guint
175 gst_bit_reader_get_pos (const GstBitReader * reader)
176 {
177   g_return_val_if_fail (reader != NULL, 0);
178
179   return reader->byte * 8 + reader->bit;
180 }
181
182 /**
183  * gst_bit_reader_get_remaining:
184  * @reader: a #GstBitReader instance
185  *
186  * Returns the remaining number of bits of a #GstBitReader instance.
187  *
188  * Returns: The remaining number of bits of @reader instance.
189  * 
190  * Since: 0.10.22
191  */
192 guint
193 gst_bit_reader_get_remaining (const GstBitReader * reader)
194 {
195   g_return_val_if_fail (reader != NULL, 0);
196
197   return reader->size * 8 - (reader->byte * 8 + reader->bit);
198 }
199
200 /**
201  * gst_bit_reader_skip:
202  * @reader: a #GstBitReader instance
203  * @nbits: the number of bits to skip
204  *
205  * Skips @nbits bits of the #GstBitReader instance.
206  *
207  * Returns: %TRUE if @nbits bits could be skipped, %FALSE otherwise.
208  * 
209  * Since: 0.10.22
210  */
211 gboolean
212 gst_bit_reader_skip (GstBitReader * reader, guint nbits)
213 {
214   g_return_val_if_fail (reader != NULL, FALSE);
215
216   if (gst_bit_reader_get_remaining (reader) < nbits)
217     return FALSE;
218
219   reader->bit += nbits;
220   reader->byte += reader->bit / 8;
221   reader->bit = reader->bit % 8;
222
223   return TRUE;
224 }
225
226 /**
227  * gst_bit_reader_skip_to_byte:
228  * @reader: a #GstBitReader instance
229  *
230  * Skips until the next byte.
231  *
232  * Returns: %TRUE if successful, %FALSE otherwise.
233  * 
234  * Since: 0.10.22
235  */
236 gboolean
237 gst_bit_reader_skip_to_byte (GstBitReader * reader)
238 {
239   g_return_val_if_fail (reader != NULL, FALSE);
240
241   if (reader->byte > reader->size)
242     return FALSE;
243
244   if (reader->bit) {
245     reader->bit = 0;
246     reader->byte++;
247   }
248
249   return TRUE;
250 }
251
252 /**
253  * gst_bit_reader_get_bits_uint8:
254  * @reader: a #GstBitReader instance
255  * @val: Pointer to a #guint8 to store the result
256  * @nbits: number of bits to read
257  *
258  * Read @nbits bits into @val and update the current position.
259  *
260  * Returns: %TRUE if successful, %FALSE otherwise.
261  * 
262  * Since: 0.10.22
263  */
264
265 /**
266  * gst_bit_reader_get_bits_uint16:
267  * @reader: a #GstBitReader instance
268  * @val: Pointer to a #guint16 to store the result
269  * @nbits: number of bits to read
270  *
271  * Read @nbits bits into @val and update the current position.
272  *
273  * Returns: %TRUE if successful, %FALSE otherwise.
274  * 
275  * Since: 0.10.22
276  */
277
278 /**
279  * gst_bit_reader_get_bits_uint32:
280  * @reader: a #GstBitReader instance
281  * @val: Pointer to a #guint32 to store the result
282  * @nbits: number of bits to read
283  *
284  * Read @nbits bits into @val and update the current position.
285  *
286  * Returns: %TRUE if successful, %FALSE otherwise.
287  * 
288  * Since: 0.10.22
289  */
290
291 /**
292  * gst_bit_reader_get_bits_uint64:
293  * @reader: a #GstBitReader instance
294  * @val: Pointer to a #guint64 to store the result
295  * @nbits: number of bits to read
296  *
297  * Read @nbits bits into @val and update the current position.
298  *
299  * Returns: %TRUE if successful, %FALSE otherwise.
300  * 
301  * Since: 0.10.22
302  */
303
304 /**
305  * gst_bit_reader_peek_bits_uint8:
306  * @reader: a #GstBitReader instance
307  * @val: Pointer to a #guint8 to store the result
308  * @nbits: number of bits to read
309  *
310  * Read @nbits bits into @val but keep the current position.
311  *
312  * Returns: %TRUE if successful, %FALSE otherwise.
313  * 
314  * Since: 0.10.22
315  */
316
317 /**
318  * gst_bit_reader_peek_bits_uint16:
319  * @reader: a #GstBitReader instance
320  * @val: Pointer to a #guint16 to store the result
321  * @nbits: number of bits to read
322  *
323  * Read @nbits bits into @val but keep the current position.
324  *
325  * Returns: %TRUE if successful, %FALSE otherwise.
326  * 
327  * Since: 0.10.22
328  */
329
330 /**
331  * gst_bit_reader_peek_bits_uint32:
332  * @reader: a #GstBitReader instance
333  * @val: Pointer to a #guint32 to store the result
334  * @nbits: number of bits to read
335  *
336  * Read @nbits bits into @val but keep the current position.
337  *
338  * Returns: %TRUE if successful, %FALSE otherwise.
339  * 
340  * Since: 0.10.22
341  */
342
343 /**
344  * gst_bit_reader_peek_bits_uint64:
345  * @reader: a #GstBitReader instance
346  * @val: Pointer to a #guint64 to store the result
347  * @nbits: number of bits to read
348  *
349  * Read @nbits bits into @val but keep the current position.
350  *
351  * Returns: %TRUE if successful, %FALSE otherwise.
352  * 
353  * Since: 0.10.22
354  */
355
356 #define GST_BIT_READER_READ_BITS(bits) \
357 gboolean \
358 gst_bit_reader_get_bits_uint##bits (GstBitReader *reader, guint##bits *val, guint nbits) \
359 { \
360   guint##bits ret = 0; \
361   \
362   g_return_val_if_fail (reader != NULL, FALSE); \
363   g_return_val_if_fail (val != NULL, FALSE); \
364   g_return_val_if_fail (nbits <= bits, FALSE); \
365   \
366   if (reader->byte * 8 + reader->bit + nbits > reader->size * 8) \
367     return FALSE; \
368   \
369   while (nbits > 0) { \
370     guint toread = MIN (nbits, 8 - reader->bit); \
371     \
372     ret <<= toread; \
373     ret |= (reader->data[reader->byte] & (0xff >> reader->bit)) >> (8 - toread - reader->bit); \
374     \
375     reader->bit += toread; \
376     if (reader->bit >= 8) { \
377       reader->byte++; \
378       reader->bit = 0; \
379     } \
380     nbits -= toread; \
381   } \
382   \
383   *val = ret; \
384   return TRUE; \
385 } \
386 \
387 gboolean \
388 gst_bit_reader_peek_bits_uint##bits (const GstBitReader *reader, guint##bits *val, guint nbits) \
389 { \
390   GstBitReader tmp; \
391   \
392   g_return_val_if_fail (reader != NULL, FALSE); \
393   tmp = *reader; \
394   return gst_bit_reader_get_bits_uint##bits (&tmp, val, nbits); \
395 }
396
397 GST_BIT_READER_READ_BITS (8);
398 GST_BIT_READER_READ_BITS (16);
399 GST_BIT_READER_READ_BITS (32);
400 GST_BIT_READER_READ_BITS (64);