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