libs: fix 'inconsistent DLL linkage' warnings on Windows
[platform/upstream/gstreamer.git] / libs / gst / base / gstbitwriter.c
1 /*
2  *  gstbitwriter.c - bitstream writer
3  *
4  *  Copyright (C) 2013 Intel Corporation
5  *  Copyright (C) 2018 Igalia, S.L.
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public License
9  *  as published by the Free Software Foundation; either version 2.1
10  *  of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free
19  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301 USA
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #define GST_BIT_WRITER_DISABLE_INLINES
28 #include "gstbitwriter.h"
29
30 /**
31  * SECTION:gstbitwriter
32  * @title: GstBitWriter
33  * @short_description: Writes any number of bits into a memory buffer
34  *
35  * #GstBitWriter provides a bit writer that can write any number of
36  * bits into a memory buffer. It provides functions for writing any
37  * number of bits into 8, 16, 32 and 64 bit variables.
38  */
39
40 /**
41  * gst_bit_writer_new:
42  *
43  * Creates a new, empty #GstBitWriter instance.
44  *
45  * Free-function: gst_bit_writer_free
46  *
47  * Returns: (transfer full): a new, empty #GstByteWriter instance
48  **/
49 GstBitWriter *
50 gst_bit_writer_new (void)
51 {
52   GstBitWriter *ret = g_slice_new0 (GstBitWriter);
53
54   ret->owned = TRUE;
55   ret->auto_grow = TRUE;
56   return ret;
57 }
58
59 /**
60  * gst_bit_writer_new_size:
61  * @size: Initial size of data in bytes
62  * @fixed: If %TRUE the data can't be reallocated
63  *
64  * Creates a #GstBitWriter instance with the given initial data size.
65  *
66  * Free-function: gst_bit_writer_free
67  *
68  * Returns: (transfer full): a new #GstBitWriter instance
69  */
70 GstBitWriter *
71 gst_bit_writer_new_with_size (guint size, gboolean fixed)
72 {
73   GstBitWriter *ret = g_slice_new0 (GstBitWriter);
74
75   gst_bit_writer_init_with_size (ret, size, fixed);
76   return ret;
77 }
78
79 /**
80  * gst_bit_writer_new_with_data:
81  * @data: Memory area for writing
82  * @size: Size of @data in bytes
83  * @initialized: if %TRUE the complete data can be read from the beginning
84  *
85  * Creates a new #GstBitWriter instance with the given memory area. If
86  * @initialized is %TRUE it is possible to read @size bits from the
87  * #GstBitWriter from the beginnig.
88  *
89  * Free-function: gst_bit_writer_free
90  *
91  * Returns: (transfer full): a new #GstBitWriter instance
92  */
93 GstBitWriter *
94 gst_bit_writer_new_with_data (guint8 * data, guint size, gboolean initialized)
95 {
96   GstBitWriter *ret = g_slice_new0 (GstBitWriter);
97
98   gst_bit_writer_init_with_data (ret, data, size, initialized);
99
100   return ret;
101 }
102
103 /**
104  * gst_bit_writer_init:
105  * @bitwriter: #GstBitWriter instance
106  *
107  * Initializes @bitwriter to an empty instance.
108  **/
109 void
110 gst_bit_writer_init (GstBitWriter * bitwriter)
111 {
112   g_return_if_fail (bitwriter != NULL);
113
114   memset (bitwriter, 0, sizeof (GstBitWriter));
115   bitwriter->owned = TRUE;
116   bitwriter->auto_grow = TRUE;
117 }
118
119 /**
120  * gst_bit_writer_init_with_size:
121  * @bitwriter: #GstBitWriter instance
122  * @size: the size on bytes to allocate for data
123  * @fixed: If %TRUE the data can't be reallocated
124  *
125  * Initializes a #GstBitWriter instance and allocates the given data
126  * @size.
127  */
128 void
129 gst_bit_writer_init_with_size (GstBitWriter * bitwriter, guint size,
130     gboolean fixed)
131 {
132   g_return_if_fail (bitwriter != NULL);
133
134   gst_bit_writer_init (bitwriter);
135
136   _gst_bit_writer_check_remaining (bitwriter, size << 3);
137
138   bitwriter->auto_grow = !fixed;
139 }
140
141 /**
142  * gst_bit_writer_init_with_data:
143  * @bitwriter: #GstBitWriter instance
144  * @data: (array length=size) (transfer none): Memory area for writing
145  * @size: Size of @data in bytes
146  * @initialized: If %TRUE the complete data can be read from the beginning
147  *
148  * Initializes @bitwriter with the given memory area @data. IF
149  * @initialized is %TRUE it is possible to read @size bits from the
150  * #GstBitWriter from the beginning.
151  */
152 void
153 gst_bit_writer_init_with_data (GstBitWriter * bitwriter, guint8 * data,
154     guint size, gboolean initialized)
155 {
156   g_return_if_fail (bitwriter != NULL);
157
158   gst_bit_writer_init (bitwriter);
159
160   bitwriter->data = data;
161   bitwriter->bit_capacity = size * 8;
162   bitwriter->bit_size = (initialized) ? size << 3 : 0;
163   bitwriter->auto_grow = FALSE;
164   bitwriter->owned = FALSE;
165 }
166
167 /**
168  * gst_bit_writer_reset:
169  * @bitwriter: #GstBitWriter instance
170  *
171  * Resets @bitwriter and frees the data if it's owned by @bitwriter.
172  */
173 void
174 gst_bit_writer_reset (GstBitWriter * bitwriter)
175 {
176   g_return_if_fail (bitwriter != NULL);
177
178   if (bitwriter->owned)
179     g_free (bitwriter->data);
180   memset (bitwriter, 0, sizeof (GstBitWriter));
181 }
182
183 /**
184  * gst_bit_writer_reset_and_get_data:
185  * @bitwriter: a #GstBitWriter instance
186  *
187  * Resets @bitwriter and returns the current data.
188  *
189  * Free-function: g_free
190  *
191  * Returns: (array) (transfer full): the current data. g_free() after
192  *     usage.
193  **/
194 guint8 *
195 gst_bit_writer_reset_and_get_data (GstBitWriter * bitwriter)
196 {
197   guint8 *data;
198
199   g_return_val_if_fail (bitwriter != NULL, NULL);
200
201   data = bitwriter->data;
202   if (bitwriter->owned)
203     data = g_memdup (data, bitwriter->bit_size >> 3);
204   gst_bit_writer_reset (bitwriter);
205
206   return data;
207 }
208
209 /**
210  * gst_bit_writer_reset_and_get_buffer:
211  * @bitwriter: a #GstBitWriter instance
212  *
213  * Resets @bitwriter and returns the current data as #GstBuffer.
214  *
215  * Free-function: gst_buffer_unref
216  *
217  * Returns: (transfer full): a new allocated #GstBuffer wrapping the
218  *     current data. gst_buffer_unref() after usage.
219  **/
220 GstBuffer *
221 gst_bit_writer_reset_and_get_buffer (GstBitWriter * bitwriter)
222 {
223   GstBuffer *buffer;
224   gpointer data;
225   gsize size;
226
227   g_return_val_if_fail (bitwriter != NULL, NULL);
228
229   size = bitwriter->bit_size >> 3;
230   data = gst_bit_writer_reset_and_get_data (bitwriter);
231
232   /* we cannot rely on buffers allocated externally, thus let's dup
233    * the data */
234   if (data && !bitwriter->owned)
235     data = g_memdup (data, size);
236
237   buffer = gst_buffer_new ();
238   if (data != NULL) {
239     gst_buffer_append_memory (buffer,
240         gst_memory_new_wrapped (0, data, size, 0, size, data, g_free));
241   }
242
243   return buffer;
244 }
245
246 /**
247  * gst_bit_writer_free:
248  * @bitwriter: (in) (transfer full): #GstBitWriter instance
249  *
250  * Frees @bitwriter and the allocated data inside.
251  */
252 void
253 gst_bit_writer_free (GstBitWriter * bitwriter)
254 {
255   g_return_if_fail (bitwriter != NULL);
256
257   gst_bit_writer_reset (bitwriter);
258   g_slice_free (GstBitWriter, bitwriter);
259 }
260
261 /**
262  * gst_bit_writer_free_and_get_data:
263  * @bitwriter: (in) (transfer full): #GstBitWriter instance
264  *
265  * Frees @bitwriter without destroying the internal data, which is
266  * returned.
267  *
268  * Free-function: g_free
269  *
270  * Returns: (array) (transfer full): the current data. g_free() after
271  *     usage.
272  **/
273 guint8 *
274 gst_bit_writer_free_and_get_data (GstBitWriter * bitwriter)
275 {
276   guint8 *data;
277
278   g_return_val_if_fail (bitwriter != NULL, NULL);
279
280   data = gst_bit_writer_reset_and_get_data (bitwriter);
281   g_slice_free (GstBitWriter, bitwriter);
282
283   return data;
284 }
285
286 /**
287  * gst_bit_writer_free_and_get_buffer:
288  * @bitwriter: (in) (transfer full): #GstBitWriter instance
289  *
290  * Frees @bitwriter without destroying the internal data, which is
291  * returned as #GstBuffer.
292  *
293  * Free-function: gst_buffer_unref
294  *
295  * Returns: (transfer full): a new allocated #GstBuffer wrapping the
296  *     data inside. gst_buffer_unref() after usage.
297  **/
298 GstBuffer *
299 gst_bit_writer_free_and_get_buffer (GstBitWriter * bitwriter)
300 {
301   GstBuffer *buffer;
302
303   g_return_val_if_fail (bitwriter != NULL, NULL);
304
305   buffer = gst_bit_writer_reset_and_get_buffer (bitwriter);
306   g_slice_free (GstBitWriter, bitwriter);
307
308   return buffer;
309 }
310
311 /**
312  * gst_bit_writer_get_size:
313  * @bitwriter: a #GstBitWriter instance
314  *
315  * Get size of written @data
316  *
317  * Returns: size of bits written in @data
318  */
319 guint
320 gst_bit_writer_get_size (const GstBitWriter * bitwriter)
321 {
322   return _gst_bit_writer_get_size_inline (bitwriter);
323 }
324
325 /**
326  * gst_bit_writer_get_data:
327  * @bitwriter: a #GstBitWriter instance
328  *
329  * Get written data pointer
330  *
331  * Returns: data pointer
332  */
333 guint8 *
334 gst_bit_writer_get_data (const GstBitWriter * bitwriter)
335 {
336   return _gst_bit_writer_get_data_inline (bitwriter);
337 }
338
339 /**
340  * gst_bit_writer_get_pos:
341  * @bitwriter: a #GstBitWriter instance
342  * @pos: The new position in bits
343  *
344  * Set the new postion of data end which should be the new size of @data.
345  *
346  * Returns: %TRUE if successful, %FALSE otherwise
347  */
348 gboolean
349 gst_bit_writer_set_pos (GstBitWriter * bitwriter, guint pos)
350 {
351   return _gst_bit_writer_set_pos_inline (bitwriter, pos);
352 }
353
354 /**
355  * gst_bit_writer_put_bits_uint8:
356  * @bitwriter: a #GstBitWriter instance
357  * @value: value of #guint8 to write
358  * @nbits: number of bits to write
359  *
360  * Write @nbits bits of @value to #GstBitWriter.
361  *
362  * Returns: %TRUE if successful, %FALSE otherwise.
363  */
364
365 /**
366  * gst_bit_writer_put_bits_uint16:
367  * @bitwriter: a #GstBitWriter instance
368  * @value: value of #guint16 to write
369  * @nbits: number of bits to write
370  *
371  * Write @nbits bits of @value to #GstBitWriter.
372  *
373  * Returns: %TRUE if successful, %FALSE otherwise.
374  */
375
376 /**
377  * gst_bit_writer_put_bits_uint32:
378  * @bitwriter: a #GstBitWriter instance
379  * @value: value of #guint32 to write
380  * @nbits: number of bits to write
381  *
382  * Write @nbits bits of @value to #GstBitWriter.
383  *
384  * Returns: %TRUE if successful, %FALSE otherwise.
385  */
386
387 /**
388  * gst_bit_writer_put_bits_uint64:
389  * @bitwriter: a #GstBitWriter instance
390  * @value: value of #guint64 to write
391  * @nbits: number of bits to write
392  *
393  * Write @nbits bits of @value to #GstBitWriter.
394  *
395  * Returns: %TRUE if successful, %FALSE otherwise.
396  */
397
398 /* *INDENT-OFF* */
399 #define GST_BIT_WRITER_WRITE_BITS(bits) \
400 gboolean \
401 gst_bit_writer_put_bits_uint##bits (GstBitWriter *bitwriter, guint##bits value, guint nbits) \
402 { \
403   return _gst_bit_writer_put_bits_uint##bits##_inline (bitwriter, value, nbits); \
404 }
405
406 GST_BIT_WRITER_WRITE_BITS (8)
407 GST_BIT_WRITER_WRITE_BITS (16)
408 GST_BIT_WRITER_WRITE_BITS (32)
409 GST_BIT_WRITER_WRITE_BITS (64)
410 #undef GST_BIT_WRITER_WRITE_BITS
411 /* *INDENT-ON* */
412
413 /**
414  * gst_bit_writer_put_bytes:
415  * @bitwriter: a #GstBitWriter instance
416  * @data: pointer of data to write
417  * @nbytes: number of bytes to write
418  *
419  * Write @nbytes bytes of @data to #GstBitWriter.
420  *
421  * Returns: %TRUE if successful, %FALSE otherwise.
422  */
423 gboolean
424 gst_bit_writer_put_bytes (GstBitWriter * bitwriter, const guint8 * data,
425     guint nbytes)
426 {
427   return _gst_bit_writer_put_bytes_inline (bitwriter, data, nbytes);
428 }
429
430 /**
431  * gst_bit_writer_align_bytes:
432  * @bitwriter: a #GstBitWriter instance
433  * @trailing_bit: trailing bits of last byte, 0 or 1
434  *
435  * Write trailing bit to align last byte of @data. @trailing_bit can
436  * only be 1 or 0.
437  *
438  * Returns: %TRUE if successful, %FALSE otherwise.
439  */
440 gboolean
441 gst_bit_writer_align_bytes (GstBitWriter * bitwriter, guint8 trailing_bit)
442 {
443   return _gst_bit_writer_align_bytes_inline (bitwriter, trailing_bit);
444 }