Merge branch 'mesa_7_6_branch'
[mesa.git] / src / gallium / auxiliary / vl / vl_bitstream_parser.c
1 #include "vl_bitstream_parser.h"
2 #include <assert.h>
3 #include <limits.h>
4 #include <util/u_memory.h>
5
6 static unsigned
7 grab_bits(unsigned cursor, unsigned how_many_bits, unsigned bitstream_elt)
8 {
9 unsigned excess_bits = sizeof(unsigned) * CHAR_BIT - how_many_bits - cursor;
10
11 assert(cursor < sizeof(unsigned) * CHAR_BIT);
12 assert(how_many_bits > 0 && how_many_bits <= sizeof(unsigned) * CHAR_BIT);
13 assert(cursor + how_many_bits <= sizeof(unsigned) * CHAR_BIT);
14
15 return (bitstream_elt << excess_bits) >> (excess_bits + cursor);
16 }
17
18 static unsigned
19 show_bits(unsigned cursor, unsigned how_many_bits, const unsigned *bitstream)
20 {
21 unsigned cur_int = cursor / (sizeof(unsigned) * CHAR_BIT);
22 unsigned cur_bit = cursor % (sizeof(unsigned) * CHAR_BIT);
23
24 assert(bitstream);
25
26 if (cur_bit + how_many_bits > sizeof(unsigned) * CHAR_BIT) {
27 unsigned lower = grab_bits(cur_bit, sizeof(unsigned) * CHAR_BIT - cur_bit,
28 bitstream[cur_int]);
29 unsigned upper = grab_bits(0, cur_bit + how_many_bits - sizeof(unsigned) * CHAR_BIT,
30 bitstream[cur_int + 1]);
31 return lower | upper << (sizeof(unsigned) * CHAR_BIT - cur_bit);
32 }
33 else
34 return grab_bits(cur_bit, how_many_bits, bitstream[cur_int]);
35 }
36
37 bool vl_bitstream_parser_init(struct vl_bitstream_parser *parser,
38 unsigned num_bitstreams,
39 const void **bitstreams,
40 const unsigned *sizes)
41 {
42 assert(parser);
43 assert(num_bitstreams);
44 assert(bitstreams);
45 assert(sizes);
46
47 parser->num_bitstreams = num_bitstreams;
48 parser->bitstreams = (const unsigned**)bitstreams;
49 parser->sizes = sizes;
50 parser->cur_bitstream = 0;
51 parser->cursor = 0;
52
53 return true;
54 }
55
56 void vl_bitstream_parser_cleanup(struct vl_bitstream_parser *parser)
57 {
58 assert(parser);
59 }
60
61 unsigned
62 vl_bitstream_parser_get_bits(struct vl_bitstream_parser *parser,
63 unsigned how_many_bits)
64 {
65 unsigned bits;
66
67 assert(parser);
68
69 bits = vl_bitstream_parser_show_bits(parser, how_many_bits);
70
71 vl_bitstream_parser_forward(parser, how_many_bits);
72
73 return bits;
74 }
75
76 unsigned
77 vl_bitstream_parser_show_bits(struct vl_bitstream_parser *parser,
78 unsigned how_many_bits)
79 {
80 unsigned bits = 0;
81 unsigned shift = 0;
82 unsigned cursor;
83 unsigned cur_bitstream;
84
85 assert(parser);
86
87 cursor = parser->cursor;
88 cur_bitstream = parser->cur_bitstream;
89
90 while (1) {
91 unsigned bits_left = parser->sizes[cur_bitstream] * CHAR_BIT - cursor;
92 unsigned bits_to_show = how_many_bits > bits_left ? bits_left : how_many_bits;
93
94 bits |= show_bits(cursor, bits_to_show,
95 parser->bitstreams[cur_bitstream]) << shift;
96
97 if (how_many_bits > bits_to_show) {
98 how_many_bits -= bits_to_show;
99 cursor = 0;
100 ++cur_bitstream;
101 shift += bits_to_show;
102 }
103 else
104 break;
105 }
106
107 return bits;
108 }
109
110 void vl_bitstream_parser_forward(struct vl_bitstream_parser *parser,
111 unsigned how_many_bits)
112 {
113 assert(parser);
114 assert(how_many_bits);
115
116 parser->cursor += how_many_bits;
117
118 while (parser->cursor > parser->sizes[parser->cur_bitstream] * CHAR_BIT) {
119 parser->cursor -= parser->sizes[parser->cur_bitstream++] * CHAR_BIT;
120 assert(parser->cur_bitstream < parser->num_bitstreams);
121 }
122 }
123
124 void vl_bitstream_parser_rewind(struct vl_bitstream_parser *parser,
125 unsigned how_many_bits)
126 {
127 signed c;
128
129 assert(parser);
130 assert(how_many_bits);
131
132 c = parser->cursor - how_many_bits;
133
134 while (c < 0) {
135 c += parser->sizes[parser->cur_bitstream--] * CHAR_BIT;
136 assert(parser->cur_bitstream < parser->num_bitstreams);
137 }
138
139 parser->cursor = (unsigned)c;
140 }