/
get_bits.h
130 lines (113 loc) · 2.97 KB
/
get_bits.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* Copyright (C) 2004 Michael Niedermayer
*
* This file may be used under the terms of the GNU Lesser General Public
* License version 2.1, a copy of which is found in LICENSE included in the
* packaging of this file.
*/
/* This was borrowed from FFmpeg */
#ifndef GET_BITS_H
#define GET_BITS_H
#include <stdint.h>
struct get_bit_context {
const uint8_t *buffer, *buffer_end;
unsigned index;
unsigned size_in_bits;
};
static inline void skip_bits(struct get_bit_context *s, int n)
{
unsigned index = s->index;
index += n;
s->index = index;
}
static inline void init_get_bits(struct get_bit_context *s, const uint8_t *buffer, unsigned bit_size)
{
s->buffer = buffer;
s->buffer_end = buffer + ((bit_size + 7) >> 3);
s->size_in_bits = bit_size;
s->index = 0;
}
static inline unsigned get_bits1(struct get_bit_context *s)
{
unsigned index = s->index;
uint8_t result = s->buffer[index >> 3];
result <<= (index & 0x07);
result >>= 8 - 1;
index++;
s->index = index;
return result;
}
union unaligned_16 { uint16_t l; } __attribute__((packed));
union unaligned_32 { uint32_t l; } __attribute__((packed));
#define AV_RN(s, p) (((const union unaligned_##s *) (p))->l)
#if defined(__i386__)
static inline uint16_t av_bswap16(uint16_t x)
{
__asm__("rorw $8, %0" : "+r"(x));
return x;
}
static inline uint32_t av_bswap32(uint32_t x)
{
__asm__("bswap %0" : "+r" (x));
return x;
}
#define AV_RB16(x) av_bswap16(AV_RN(16, x))
#define AV_RB32(x) av_bswap32(AV_RN(32, x))
#elif defined(__arm__)
static inline uint16_t av_read16_be(const uint8_t *p)
{
uint16_t v;
__asm__("ldrh %0, %1\n\trev16 %0, %0" : "=r"(v) : "m"(*(const uint16_t *)p));
return v;
}
static inline uint32_t av_read32_be(const uint8_t *p)
{
uint32_t v;
__asm__("ldr %0, %1" : "=r"(v) : "m"(*(const uint32_t *)p));
__asm__("rev %0, %0" : "+r"(v));
return v;
}
#define AV_RB16(x) av_read16_be(x)
#define AV_RB32(x) av_read32_be(x)
#endif
#ifndef AV_RB16
#define AV_RB16(x) \
((((const uint8_t *)(x))[0] << 8) | \
((const uint8_t *)(x))[1])
#endif
#ifndef AV_RB32
#define AV_RB32(x) \
((((const uint8_t *)(x))[0] << 24) | \
(((const uint8_t *)(x))[1] << 16) | \
(((const uint8_t *)(x))[2] << 8) | \
((const uint8_t *)(x))[3])
#endif
static inline unsigned get_bits(struct get_bit_context *s, int n)
{
unsigned index = s->index;
int re_cache = 0;
register int tmp;
re_cache = AV_RB32(((const uint8_t *)s->buffer) + (index >> 3)) << (index & 0x07);
tmp = ((uint32_t)re_cache) >> (32 - n);
index += n;
s->index = index;
return tmp;
}
static inline unsigned show_bits(struct get_bit_context *s, int n)
{
unsigned index = s->index;
int re_cache = 0;
register int tmp;
re_cache = AV_RB32(((const uint8_t *)s->buffer) + (index >> 3)) << (index & 0x07);
tmp = ((uint32_t)re_cache) >> (32 - n);
return tmp;
}
static inline unsigned get_bits_count(const struct get_bit_context *s)
{
return s->index;
}
static inline int get_bits_left(const struct get_bit_context *s)
{
return s->size_in_bits - get_bits_count(s);
}
#endif