Mstdlib-1.24.0
|
Typedefs | |
typedef struct M_bit_buf | M_bit_buf_t |
Enumerations | |
enum | M_bit_buf_pad_t { M_BIT_BUF_PAD_NONE = 0 , M_BIT_BUF_PAD_BEFORE , M_BIT_BUF_PAD_AFTER } |
Functions | |
M_bit_buf_t * | M_bit_buf_create (void) M_WARN_UNUSED_RESULT M_MALLOC |
void | M_bit_buf_destroy (M_bit_buf_t *bbuf) M_FREE(1) |
M_uint8 * | M_bit_buf_finish (M_bit_buf_t *bbuf, size_t *nbytes) M_FREE(1) M_WARN_UNUSED_RESULT M_MALLOC |
M_buf_t * | M_bit_buf_finish_buf (M_bit_buf_t *bbuf) M_FREE(1) M_WARN_UNUSED_RESULT M_MALLOC |
size_t | M_bit_buf_len (const M_bit_buf_t *bbuf) |
size_t | M_bit_buf_len_bytes (const M_bit_buf_t *bbuf) |
const M_uint8 * | M_bit_buf_peek (const M_bit_buf_t *bbuf) |
void | M_bit_buf_truncate (M_bit_buf_t *bbuf, size_t len_bits) |
void | M_bit_buf_fill (M_bit_buf_t *bbuf, M_uint8 bit, size_t len_bits) |
void | M_bit_buf_add_bit (M_bit_buf_t *bbuf, M_uint8 bit) |
void | M_bit_buf_set_bit (M_bit_buf_t *bbuf, M_uint8 bit, size_t bit_idx, M_uint8 fill_bit) |
M_bool | M_bit_buf_update_bit (M_bit_buf_t *bbuf, size_t bit_idx, M_uint8 bit) |
void | M_bit_buf_add_bytes (M_bit_buf_t *bbuf, const void *bytes, size_t nbits) |
void | M_bit_buf_add (M_bit_buf_t *bbuf, M_uint64 bits, size_t nbits, M_bit_buf_pad_t pad) |
M_bool | M_bit_buf_add_bitstr (M_bit_buf_t *bbuf, const char *bitstr, M_bit_buf_pad_t pad) |
void | M_bit_buf_reserve (M_bit_buf_t *bbuf, size_t nbits) |
Allows for buffered writing of data that's organized per-bit, instead of per-byte.
Also allows for changing bits that were previously added to the buffer (see M_bit_buf_update_bit()). This allows for random-access setting of individual bits. For example, if you're generating a bit-level image, you can fill the buffer with zero bits, and then set individual bits afterwards in whatever order you wish.
When you're done adding data, the contents of the buffer can be output as a continuous byte-array, either raw as an (M_uint8 *), or inside a regular per-byte M_buf_t.
Example (creating a buffer, adding data, finishing the buffer):
typedef struct M_bit_buf M_bit_buf_t |
enum M_bit_buf_pad_t |
Enumeration for byte-alignment padding mode for M_bit_buf_add().
M_bit_buf_t * M_bit_buf_create | ( | void | ) |
Create a new bit buffer.
void M_bit_buf_destroy | ( | M_bit_buf_t * | bbuf | ) |
Free a bit buffer, discarding its data.
[in] | bbuf | bit buffer to destroy |
M_uint8 * M_bit_buf_finish | ( | M_bit_buf_t * | bbuf, |
size_t * | nbytes | ||
) |
Free a buffer, saving its data.
The caller is responsible for freeing the data.
[in] | bbuf | Bit buffer |
[out] | nbytes | Data length (in bytes) |
M_buf_t * M_bit_buf_finish_buf | ( | M_bit_buf_t * | bbuf | ) |
Free a buffer, saving its data in a per-byte buffer.
The caller is responsible for freeing the data.
[in] | bbuf | Bit buffer |
size_t M_bit_buf_len | ( | const M_bit_buf_t * | bbuf | ) |
Return the length of the data held by a buffer, in bits.
[in] | bbuf | Bit buffer |
size_t M_bit_buf_len_bytes | ( | const M_bit_buf_t * | bbuf | ) |
Return the length of the data held by a buffer, in bytes.
Partial bytes will be rounded up (i.e., 9 bits stored == 2 bytes).
[in] | bbuf | Bit buffer |
const M_uint8 * M_bit_buf_peek | ( | const M_bit_buf_t * | bbuf | ) |
Return pointer to internal buffer data.
The internal data is stored as an array of bytes. The first bit in the buffer is always guaranteed to be the highest bit in the first byte, second bit in the buffer is the next highest bit, and so on. The implementation guarantees this will always be the case, regardless of what operations you may have done on the bit buffer.
[in] | bbuf | Bit buffer |
void M_bit_buf_truncate | ( | M_bit_buf_t * | bbuf, |
size_t | len_bits | ||
) |
Truncate the length of the data to the specified size (in bits).
Removes data from the end of the buffer.
[in,out] | bbuf | Bit buffer |
[in] | len_bits | Length (in bits) to truncate buffer to |
void M_bit_buf_fill | ( | M_bit_buf_t * | bbuf, |
M_uint8 | bit, | ||
size_t | len_bits | ||
) |
Add a number of repetitions of the same bit to the buffer.
[in,out] | bbuf | Bit buffer |
[in] | bit | 1 (to add a set bit) or 0 (to add an unset bit) |
[in] | len_bits | Number of bits to add |
void M_bit_buf_add_bit | ( | M_bit_buf_t * | bbuf, |
M_uint8 | bit | ||
) |
Add the given bit to the buffer.
[in,out] | bbuf | Bit buffer |
[in] | bit | 1 (to add a set bit) or 0 (to add an unset bit) |
void M_bit_buf_set_bit | ( | M_bit_buf_t * | bbuf, |
M_uint8 | bit, | ||
size_t | bit_idx, | ||
M_uint8 | fill_bit | ||
) |
Add given bit at given location in buffer, filling in gaps as necessary.
If the requested bit_idx has already been set in the buffer, this function will simply update it to the requested value.
If the requested bit_idx hasn't already been set, the size of the buffer will be increased up to the requested bit_idx, and then that bit will be set. Any new bits that had to be added before the requested bit_idx will be set to the value of 'fill_bit'.
If you only want to update bits that have already been set, use M_bit_buf_update_bit().
Usage example:
M_bool M_bit_buf_update_bit | ( | M_bit_buf_t * | bbuf, |
size_t | bit_idx, | ||
M_uint8 | bit | ||
) |
Change one of the bits already in the buffer.
This function is guaranteed to never change the length of the bit stream - it will only update bits that are already present. If you want to add a bit past the end of the stream, and automatically fill any bits between the old end of the stream and the new bit, use M_bit_buf_set_bit().
[in] | bbuf | Bit buffer |
[in] | bit_idx | index of bit to change, must be less than M_bit_buf_len() |
[in] | bit | 1 to set the bit, 0 to unset it |
void M_bit_buf_add_bytes | ( | M_bit_buf_t * | bbuf, |
const void * | bytes, | ||
size_t | nbits | ||
) |
Add bits from the given variable-length chunk of data.
[in,out] | bbuf | Bit buffer |
[in] | bytes | data to add |
[in] | nbits | number of bits to add from the given data |
void M_bit_buf_add | ( | M_bit_buf_t * | bbuf, |
M_uint64 | bits, | ||
size_t | nbits, | ||
M_bit_buf_pad_t | pad | ||
) |
Add bits from a given integer to the buffer.
Note that the bit region being read is assumed to be justified against the least-significant end of the integer, though the bits within that region are read from most-significant to least-significant.
For example, if bits == 0x8B == (10001011)b, and nbits == 4, the bits "1011" will be added to the buffer.
[in,out] | bbuf | Bit buffer |
[in] | bits | Value to draw bits from |
[in] | nbits | Number of bits to use (counted from least-significant end, right-to-left) |
[in] | pad | Should any bits be added to force the result to end on a byte-boundary |
M_bool M_bit_buf_add_bitstr | ( | M_bit_buf_t * | bbuf, |
const char * | bitstr, | ||
M_bit_buf_pad_t | pad | ||
) |
Add bits from a given binary-ascii string to the buffer.
A binary-ascii string is a list of 1 and 0 characters (e.g., "100010").
Any whitespace in the string will be silently ignored. So, " 1000 1 0" will add the same data as "100010".
[in,out] | bbuf | Bit buffer |
[in] | bitstr | String to draw bits from |
[in] | pad | Should any bits be added to force the result to end on a byte-boundary |
void M_bit_buf_reserve | ( | M_bit_buf_t * | bbuf, |
size_t | nbits | ||
) |
Provide hint to buffer about how many bits we're going to add.
If you know ahead of time how many bits are going to get added to the buffer, you can use this function to grow the buffer all at once ahead of time, instead of on-demand as the buffer runs out of internal space.
This is provided purely as a performance hint.
bbuf | Bit buffer |
nbits | Number of bits that we expect to add in the future |