gstbitreader.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  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. #ifndef __GST_BIT_READER_H__
  21. #define __GST_BIT_READER_H__
  22. #include <gst/gst.h>
  23. /* FIXME: inline functions */
  24. G_BEGIN_DECLS
  25. #define GST_BIT_READER(reader) ((GstBitReader *) (reader))
  26. /**
  27. * GstBitReader:
  28. * @data: (array length=size): Data from which the bit reader will
  29. * read
  30. * @size: Size of @data in bytes
  31. * @byte: Current byte position
  32. * @bit: Bit position in the current byte
  33. *
  34. * A bit reader instance.
  35. */
  36. typedef struct {
  37. const guint8 *data;
  38. guint size;
  39. guint byte; /* Byte position */
  40. guint bit; /* Bit position in the current byte */
  41. /* < private > */
  42. gpointer _gst_reserved[GST_PADDING];
  43. } GstBitReader;
  44. GstBitReader * gst_bit_reader_new (const guint8 *data, guint size) G_GNUC_MALLOC;
  45. void gst_bit_reader_free (GstBitReader *reader);
  46. void gst_bit_reader_init (GstBitReader *reader, const guint8 *data, guint size);
  47. gboolean gst_bit_reader_set_pos (GstBitReader *reader, guint pos);
  48. guint gst_bit_reader_get_pos (const GstBitReader *reader);
  49. guint gst_bit_reader_get_remaining (const GstBitReader *reader);
  50. guint gst_bit_reader_get_size (const GstBitReader *reader);
  51. gboolean gst_bit_reader_skip (GstBitReader *reader, guint nbits);
  52. gboolean gst_bit_reader_skip_to_byte (GstBitReader *reader);
  53. gboolean gst_bit_reader_get_bits_uint8 (GstBitReader *reader, guint8 *val, guint nbits);
  54. gboolean gst_bit_reader_get_bits_uint16 (GstBitReader *reader, guint16 *val, guint nbits);
  55. gboolean gst_bit_reader_get_bits_uint32 (GstBitReader *reader, guint32 *val, guint nbits);
  56. gboolean gst_bit_reader_get_bits_uint64 (GstBitReader *reader, guint64 *val, guint nbits);
  57. gboolean gst_bit_reader_peek_bits_uint8 (const GstBitReader *reader, guint8 *val, guint nbits);
  58. gboolean gst_bit_reader_peek_bits_uint16 (const GstBitReader *reader, guint16 *val, guint nbits);
  59. gboolean gst_bit_reader_peek_bits_uint32 (const GstBitReader *reader, guint32 *val, guint nbits);
  60. gboolean gst_bit_reader_peek_bits_uint64 (const GstBitReader *reader, guint64 *val, guint nbits);
  61. /**
  62. * GST_BIT_READER_INIT:
  63. * @data: Data from which the #GstBitReader should read
  64. * @size: Size of @data in bytes
  65. *
  66. * A #GstBitReader must be initialized with this macro, before it can be
  67. * used. This macro can used be to initialize a variable, but it cannot
  68. * be assigned to a variable. In that case you have to use
  69. * gst_bit_reader_init().
  70. */
  71. #define GST_BIT_READER_INIT(data, size) {data, size, 0, 0}
  72. /* Unchecked variants */
  73. static inline void
  74. gst_bit_reader_skip_unchecked (GstBitReader * reader, guint nbits)
  75. {
  76. reader->bit += nbits;
  77. reader->byte += reader->bit / 8;
  78. reader->bit = reader->bit % 8;
  79. }
  80. static inline void
  81. gst_bit_reader_skip_to_byte_unchecked (GstBitReader * reader)
  82. {
  83. if (reader->bit) {
  84. reader->bit = 0;
  85. reader->byte++;
  86. }
  87. }
  88. #define __GST_BIT_READER_READ_BITS_UNCHECKED(bits) \
  89. static inline guint##bits \
  90. gst_bit_reader_peek_bits_uint##bits##_unchecked (const GstBitReader *reader, guint nbits) \
  91. { \
  92. guint##bits ret = 0; \
  93. const guint8 *data; \
  94. guint byte, bit; \
  95. \
  96. data = reader->data; \
  97. byte = reader->byte; \
  98. bit = reader->bit; \
  99. \
  100. while (nbits > 0) { \
  101. guint toread = MIN (nbits, 8 - bit); \
  102. \
  103. ret <<= toread; \
  104. ret |= (data[byte] & (0xff >> bit)) >> (8 - toread - bit); \
  105. \
  106. bit += toread; \
  107. if (bit >= 8) { \
  108. byte++; \
  109. bit = 0; \
  110. } \
  111. nbits -= toread; \
  112. } \
  113. \
  114. return ret; \
  115. } \
  116. \
  117. static inline guint##bits \
  118. gst_bit_reader_get_bits_uint##bits##_unchecked (GstBitReader *reader, guint nbits) \
  119. { \
  120. guint##bits ret; \
  121. \
  122. ret = gst_bit_reader_peek_bits_uint##bits##_unchecked (reader, nbits); \
  123. \
  124. gst_bit_reader_skip_unchecked (reader, nbits); \
  125. \
  126. return ret; \
  127. }
  128. __GST_BIT_READER_READ_BITS_UNCHECKED (8)
  129. __GST_BIT_READER_READ_BITS_UNCHECKED (16)
  130. __GST_BIT_READER_READ_BITS_UNCHECKED (32)
  131. __GST_BIT_READER_READ_BITS_UNCHECKED (64)
  132. #undef __GST_BIT_READER_READ_BITS_UNCHECKED
  133. /* unchecked variants -- do not use */
  134. static inline guint
  135. _gst_bit_reader_get_size_unchecked (const GstBitReader * reader)
  136. {
  137. return reader->size * 8;
  138. }
  139. static inline guint
  140. _gst_bit_reader_get_pos_unchecked (const GstBitReader * reader)
  141. {
  142. return reader->byte * 8 + reader->bit;
  143. }
  144. static inline guint
  145. _gst_bit_reader_get_remaining_unchecked (const GstBitReader * reader)
  146. {
  147. return reader->size * 8 - (reader->byte * 8 + reader->bit);
  148. }
  149. /* inlined variants -- do not use directly */
  150. static inline guint
  151. _gst_bit_reader_get_size_inline (const GstBitReader * reader)
  152. {
  153. g_return_val_if_fail (reader != NULL, 0);
  154. return _gst_bit_reader_get_size_unchecked (reader);
  155. }
  156. static inline guint
  157. _gst_bit_reader_get_pos_inline (const GstBitReader * reader)
  158. {
  159. g_return_val_if_fail (reader != NULL, 0);
  160. return _gst_bit_reader_get_pos_unchecked (reader);
  161. }
  162. static inline guint
  163. _gst_bit_reader_get_remaining_inline (const GstBitReader * reader)
  164. {
  165. g_return_val_if_fail (reader != NULL, 0);
  166. return _gst_bit_reader_get_remaining_unchecked (reader);
  167. }
  168. static inline gboolean
  169. _gst_bit_reader_skip_inline (GstBitReader * reader, guint nbits)
  170. {
  171. g_return_val_if_fail (reader != NULL, FALSE);
  172. if (_gst_bit_reader_get_remaining_unchecked (reader) < nbits)
  173. return FALSE;
  174. gst_bit_reader_skip_unchecked (reader, nbits);
  175. return TRUE;
  176. }
  177. static inline gboolean
  178. _gst_bit_reader_skip_to_byte_inline (GstBitReader * reader)
  179. {
  180. g_return_val_if_fail (reader != NULL, FALSE);
  181. if (reader->byte > reader->size)
  182. return FALSE;
  183. gst_bit_reader_skip_to_byte_unchecked (reader);
  184. return TRUE;
  185. }
  186. #define __GST_BIT_READER_READ_BITS_INLINE(bits) \
  187. static inline gboolean \
  188. _gst_bit_reader_get_bits_uint##bits##_inline (GstBitReader *reader, guint##bits *val, guint nbits) \
  189. { \
  190. g_return_val_if_fail (reader != NULL, FALSE); \
  191. g_return_val_if_fail (val != NULL, FALSE); \
  192. g_return_val_if_fail (nbits <= bits, FALSE); \
  193. \
  194. if (_gst_bit_reader_get_remaining_unchecked (reader) < nbits) \
  195. return FALSE; \
  196. \
  197. *val = gst_bit_reader_get_bits_uint##bits##_unchecked (reader, nbits); \
  198. return TRUE; \
  199. } \
  200. \
  201. static inline gboolean \
  202. _gst_bit_reader_peek_bits_uint##bits##_inline (const GstBitReader *reader, guint##bits *val, guint nbits) \
  203. { \
  204. g_return_val_if_fail (reader != NULL, FALSE); \
  205. g_return_val_if_fail (val != NULL, FALSE); \
  206. g_return_val_if_fail (nbits <= bits, FALSE); \
  207. \
  208. if (_gst_bit_reader_get_remaining_unchecked (reader) < nbits) \
  209. return FALSE; \
  210. \
  211. *val = gst_bit_reader_peek_bits_uint##bits##_unchecked (reader, nbits); \
  212. return TRUE; \
  213. }
  214. __GST_BIT_READER_READ_BITS_INLINE (8)
  215. __GST_BIT_READER_READ_BITS_INLINE (16)
  216. __GST_BIT_READER_READ_BITS_INLINE (32)
  217. __GST_BIT_READER_READ_BITS_INLINE (64)
  218. #undef __GST_BIT_READER_READ_BITS_INLINE
  219. #ifndef GST_BIT_READER_DISABLE_INLINES
  220. #define gst_bit_reader_get_size(reader) \
  221. _gst_bit_reader_get_size_inline (reader)
  222. #define gst_bit_reader_get_pos(reader) \
  223. _gst_bit_reader_get_pos_inline (reader)
  224. #define gst_bit_reader_get_remaining(reader) \
  225. _gst_bit_reader_get_remaining_inline (reader)
  226. /* we use defines here so we can add the G_LIKELY() */
  227. #define gst_bit_reader_skip(reader, nbits)\
  228. G_LIKELY (_gst_bit_reader_skip_inline(reader, nbits))
  229. #define gst_bit_reader_skip_to_byte(reader)\
  230. G_LIKELY (_gst_bit_reader_skip_to_byte_inline(reader))
  231. #define gst_bit_reader_get_bits_uint8(reader, val, nbits) \
  232. G_LIKELY (_gst_bit_reader_get_bits_uint8_inline (reader, val, nbits))
  233. #define gst_bit_reader_get_bits_uint16(reader, val, nbits) \
  234. G_LIKELY (_gst_bit_reader_get_bits_uint16_inline (reader, val, nbits))
  235. #define gst_bit_reader_get_bits_uint32(reader, val, nbits) \
  236. G_LIKELY (_gst_bit_reader_get_bits_uint32_inline (reader, val, nbits))
  237. #define gst_bit_reader_get_bits_uint64(reader, val, nbits) \
  238. G_LIKELY (_gst_bit_reader_get_bits_uint64_inline (reader, val, nbits))
  239. #define gst_bit_reader_peek_bits_uint8(reader, val, nbits) \
  240. G_LIKELY (_gst_bit_reader_peek_bits_uint8_inline (reader, val, nbits))
  241. #define gst_bit_reader_peek_bits_uint16(reader, val, nbits) \
  242. G_LIKELY (_gst_bit_reader_peek_bits_uint16_inline (reader, val, nbits))
  243. #define gst_bit_reader_peek_bits_uint32(reader, val, nbits) \
  244. G_LIKELY (_gst_bit_reader_peek_bits_uint32_inline (reader, val, nbits))
  245. #define gst_bit_reader_peek_bits_uint64(reader, val, nbits) \
  246. G_LIKELY (_gst_bit_reader_peek_bits_uint64_inline (reader, val, nbits))
  247. #endif
  248. G_END_DECLS
  249. #endif /* __GST_BIT_READER_H__ */