gpu_neon: fix some missing ebuf updates
[pcsx_rearmed.git] / deps / libretro-common / formats / libchdr / 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  *  bitstream_peek - fetch the requested number of bits
39  *  but don't advance the input pointer
40  *-----------------------------------------------------
41  */
42
43 uint32_t bitstream_peek(struct bitstream* bitstream, int numbits)
44 {
45         if (numbits == 0)
46                 return 0;
47
48         /* fetch data if we need more */
49         if (numbits > bitstream->bits)
50         {
51                 while (bitstream->bits <= 24)
52                 {
53                         if (bitstream->doffset < bitstream->dlength)
54                                 bitstream->buffer |= bitstream->read[bitstream->doffset] << (24 - bitstream->bits);
55                         bitstream->doffset++;
56                         bitstream->bits += 8;
57                 }
58         }
59
60         /* return the data */
61         return bitstream->buffer >> (32 - numbits);
62 }
63
64 /*-----------------------------------------------------
65  *  bitstream_remove - advance the input pointer by the
66  *  specified number of bits
67  *-----------------------------------------------------
68  */
69
70 void bitstream_remove(struct bitstream* bitstream, int numbits)
71 {
72         bitstream->buffer <<= numbits;
73         bitstream->bits -= numbits;
74 }
75
76 /*-----------------------------------------------------
77  *  bitstream_read - fetch the requested number of bits
78  *-----------------------------------------------------
79  */
80
81 uint32_t bitstream_read(struct bitstream* bitstream, int numbits)
82 {
83         uint32_t result = bitstream_peek(bitstream, numbits);
84         bitstream_remove(bitstream, numbits);
85         return result;
86 }
87
88 /*-------------------------------------------------
89  *  read_offset - return the current read offset
90  *-------------------------------------------------
91  */
92
93 uint32_t bitstream_read_offset(struct bitstream* bitstream)
94 {
95         uint32_t result = bitstream->doffset;
96         int bits = bitstream->bits;
97         while (bits >= 8)
98         {
99                 result--;
100                 bits -= 8;
101         }
102         return result;
103 }
104
105 /*-------------------------------------------------
106  *  flush - flush to the nearest byte
107  *-------------------------------------------------
108  */
109
110 uint32_t bitstream_flush(struct bitstream* bitstream)
111 {
112         while (bitstream->bits >= 8)
113         {
114                 bitstream->doffset--;
115                 bitstream->bits -= 8;
116         }
117         bitstream->bits = bitstream->buffer = 0;
118         return bitstream->doffset;
119 }