duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

libchdr_bitstream.c (3209B)


      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