gpu_neon: fix some missing ebuf updates
[pcsx_rearmed.git] / deps / libchdr / src / libchdr_bitstream.c
1 /* license:BSD-3-Clause
2  * copyright-holders:Aaron Giles
3 ***************************************************************************
4
5     bitstream.c
6
7     Helper classes for reading/writing at the bit level.
8
9 ***************************************************************************/
10
11 #include <stdlib.h>
12 #include <libchdr/bitstream.h>
13
14 /***************************************************************************
15  *  INLINE FUNCTIONS
16  ***************************************************************************
17  */
18
19 int bitstream_overflow(struct bitstream* bitstream) { return ((bitstream->doffset - bitstream->bits / 8) > bitstream->dlength); }
20
21 /*-------------------------------------------------
22  *  create_bitstream - constructor
23  *-------------------------------------------------
24  */
25
26 struct bitstream* create_bitstream(const void *src, uint32_t srclength)
27 {
28         struct bitstream* bitstream = (struct bitstream*)malloc(sizeof(struct bitstream));
29         bitstream->buffer = 0;
30         bitstream->bits = 0;
31         bitstream->read = (const uint8_t*)src;
32         bitstream->doffset = 0;
33         bitstream->dlength = srclength;
34         return bitstream;
35 }
36
37
38 /*-----------------------------------------------------
39  *  bitstream_peek - fetch the requested number of bits
40  *  but don't advance the input pointer
41  *-----------------------------------------------------
42  */
43
44 uint32_t bitstream_peek(struct bitstream* bitstream, int numbits)
45 {
46         if (numbits == 0)
47                 return 0;
48
49         /* fetch data if we need more */
50         if (numbits > bitstream->bits)
51         {
52                 while (bitstream->bits <= 24)
53                 {
54                         if (bitstream->doffset < bitstream->dlength)
55                                 bitstream->buffer |= bitstream->read[bitstream->doffset] << (24 - bitstream->bits);
56                         bitstream->doffset++;
57                         bitstream->bits += 8;
58                 }
59         }
60
61         /* return the data */
62         return bitstream->buffer >> (32 - numbits);
63 }
64
65
66 /*-----------------------------------------------------
67  *  bitstream_remove - advance the input pointer by the
68  *  specified number of bits
69  *-----------------------------------------------------
70  */
71
72 void bitstream_remove(struct bitstream* bitstream, int numbits)
73 {
74         bitstream->buffer <<= numbits;
75         bitstream->bits -= numbits;
76 }
77
78
79 /*-----------------------------------------------------
80  *  bitstream_read - fetch the requested number of bits
81  *-----------------------------------------------------
82  */
83
84 uint32_t bitstream_read(struct bitstream* bitstream, int numbits)
85 {
86         uint32_t result = bitstream_peek(bitstream, numbits);
87         bitstream_remove(bitstream, numbits);
88         return result;
89 }
90
91
92 /*-------------------------------------------------
93  *  read_offset - return the current read offset
94  *-------------------------------------------------
95  */
96
97 uint32_t bitstream_read_offset(struct bitstream* bitstream)
98 {
99         uint32_t result = bitstream->doffset;
100         int bits = bitstream->bits;
101         while (bits >= 8)
102         {
103                 result--;
104                 bits -= 8;
105         }
106         return result;
107 }
108
109
110 /*-------------------------------------------------
111  *  flush - flush to the nearest byte
112  *-------------------------------------------------
113  */
114
115 uint32_t bitstream_flush(struct bitstream* bitstream)
116 {
117         while (bitstream->bits >= 8)
118         {
119                 bitstream->doffset--;
120                 bitstream->bits -= 8;
121         }
122         bitstream->bits = bitstream->buffer = 0;
123         return bitstream->doffset;
124 }
125