/*
* GPAC - Multimedia Framework C SDK
*
* Authors: Jean Le Feuvre
* Copyright (c) Telecom ParisTech 2000-2012
* All rights reserved
*
* This file is part of GPAC / common tools sub-project
*
* GPAC is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* GPAC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef _GF_BITSTREAM_H_
#define _GF_BITSTREAM_H_
#ifdef __cplusplus
extern "C" {
#endif
/*!
* \file <gpac/bitstream.h>
* \brief bitstream reading and writing.
*/
/*!
* \addtogroup bs_grp Bitstream
* \ingroup utils_grp
* \brief BitStream object
*
* This section documents the bitstream object of the GPAC framework.
* \note Unless specified, all functions assume Big-Endian ordering of data in the bitstream.
* @{
*/
#include <gpac/tools.h>
enum
{
GF_BITSTREAM_READ = 0,
GF_BITSTREAM_WRITE
};
typedef struct __tag_bitstream GF_BitStream;
/*!
* \brief bitstream constructor
*
* Constructs a bitstream from a buffer (read or write mode)
* \param buffer buffer to read or write. In WRITE mode, this can be NULL to let the bitstream object dynamically allocate memory, in which case the size param is ignored.
* \param size size of the buffer given.
* \param mode operation mode for this bitstream: GF_BITSTREAM_READ for read, GF_BITSTREAM_WRITE for write.
* \return new bitstream object
* \note In write mode on an existing data buffer, data overflow is never signaled but simply ignored, it is the caller responsability to ensure it
* does not write more than possible.
*/
GF_BitStream *gf_bs_new(const char *buffer, u64 size, u32 mode);
/*!
* \brief bitstream constructor from file handle
*
* Creates a bitstream from a file handle.
* \param f handle of the file to use. This handle must be created with binary mode.
* \param mode operation mode for this bitstream: GF_BITSTREAM_READ for read, GF_BITSTREAM_WRITE for write.
* \return new bitstream object
* \note - You have to open your file in the appropriated mode:\n
* - GF_BITSTREAM_READ: bitstream is constructed for reading\n
* - GF_BITSTREAM_WRITE: bitstream is constructed for writing\n
* \note - you may use any of these modes for a file with read/write access.
* \warning RESULTS ARE UNEXPECTED IF YOU TOUCH THE FILE WHILE USING THE BITSTREAM.
*/
GF_BitStream *gf_bs_from_file(FILE *f, u32 mode);
/*!
* \brief bitstream constructor from file handle
*
* Deletes the bitstream object. If the buffer was created by the bitstream, it is deleted if still present.
*/
void gf_bs_del(GF_BitStream *bs);
/*!
* \brief sets bitstream write cache size
*
* Sets the write cache size for file-based bitstreams.
* \param bs the target bitstream
* \param size size of the write cache in bytes
* \return error if any.
*/
GF_Err gf_bs_set_output_buffering(GF_BitStream *bs, u32 size);
/*!
* \brief gets bitstream write cache size
*
* Gets the write cache size for file-based bitstreams.
* \param bs the target bitstream
* \return size of the write cache in bytes, 0 if no cache
*/
u32 gf_bs_get_output_buffering(GF_BitStream *bs);
/*!
* \brief integer reading
*
* Reads an integer coded on a number of bit.
* \param bs the target bitstream
* \param nBits the number of bits to read
* \return the integer value read.
*/
u32 gf_bs_read_int(GF_BitStream *bs, u32 nBits);
/*!
* \brief large integer reading
*
* Reads a large integer coded on a number of bit bigger than 32.
* \param bs the target bitstream
* \param nBits the number of bits to read
* \return the large integer value read.
*/
u64 gf_bs_read_long_int(GF_BitStream *bs, u32 nBits);
/*!
* \brief float reading
*
* Reads a float coded as IEEE 32 bit format.
* \param bs the target bitstream
* \return the float value read.
*/
Float gf_bs_read_float(GF_BitStream *bs);
/*!
* \brief double reading
*
* Reads a double coded as IEEE 64 bit format.
* \param bs the target bitstream
* \return the double value read.
*/
Double gf_bs_read_double(GF_BitStream *bs);
/*!
* \brief data reading
*
* Reads a data buffer
* \param bs the target bitstream
* \param data the data buffer to be filled
* \param nbBytes the amount of bytes to read
* \return the number of bytes actually read.
* \warning the data buffer passed must be large enough to hold the desired amount of bytes.
*/
u32 gf_bs_read_data(GF_BitStream *bs, char *data, u32 nbBytes);
/*!
* \brief align char reading
*
* Reads an integer coded on 8 bits starting at a byte boundary in the bitstream.
* \warning you must not use this function if the bitstream is not aligned
* \param bs the target bitstream
* \return the char value read.
*/
u32 gf_bs_read_u8(GF_BitStream *bs);
/*!
* \brief align char reading until reaching the given value
*
* Reads an integer coded on 8 bits starting at a byte boundary in the bitstream until
* the given appears on the bitstream.
* \note the bytes read in the bitstream will only be update if the delimiter is found
* \param bs the target bitstream
* \param delimiter the stop condition
* \param out the resulting value
* \param max_length the maximum length of the output
* \return the number of value read.
*/
u32 gf_bs_read_u8_until_delimiter(GF_BitStream *bs, u8 delimiter, u8* out, u32 max_length);
/*!
* \brief align short reading
*
* Reads an integer coded on 16 bits starting at a byte boundary in the bitstream.
* \warning you must not use this function if the bitstream is not aligned
* \param bs the target bitstream
* \return the short value read.
*/
u32 gf_bs_read_u16(GF_BitStream *bs);
/*!
* \brief align 24-bit integer reading
*
* Reads an integer coded on 24 bits starting at a byte boundary in the bitstream.
* \warning you must not use this function if the bitstream is not aligned
* \param bs the target bitstream
* \return the integer value read.
*/
u32 gf_bs_read_u24(GF_BitStream *bs);
/*!
* \brief align integer reading
*
* Reads an integer coded on 32 bits starting at a byte boundary in the bitstream.
* \warning you must not use this function if the bitstream is not aligned
* \param bs the target bitstream
* \return the integer value read.
*/
u32 gf_bs_read_u32(GF_BitStream *bs);
/*!
* \brief align large integer reading
*
* Reads an integer coded on 64 bits starting at a byte boundary in the bitstream.
* \warning you must not use this function if the bitstream is not aligned
* \param bs the target bitstream
* \return the large integer value read.
*/
u64 gf_bs_read_u64(GF_BitStream *bs);
/*!
* \brief little endian integer reading
*
* Reads an integer coded on 32 bits in little-endian order.
* \param bs the target bitstream
* \return the integer value read.
*/
u32 gf_bs_read_u32_le(GF_BitStream *bs);
/*!
* \brief little endian integer reading
*
* Reads an integer coded on 16 bits in little-endian order.
* \param bs the target bitstream
* \return the integer value read.
*/
u16 gf_bs_read_u16_le(GF_BitStream *bs);
/*!
* \brief variable length integer reading
*
* Reads an integer coded on a variable number of 4-bits chunks. The number of chunks is given by the number of non-0 bits at the beginning.
* \param bs the target bitstream
* \return the integer value read.
*/
u32 gf_bs_read_vluimsbf5(GF_BitStream *bs);
/*!
* \brief bit position
*
* Returns current bit position in the bitstream - only works in memory mode.
* \param bs the target bitstream
* \return the integer value read.
*/
u32 gf_bs_get_bit_offset(GF_BitStream *bs);
/*!
* \brief current bit position
*
* Returns bit position in the current byte of the bitstream - only works in memory mode.
* \param bs the target bitstream
* \return the integer value read.
*/
u32 gf_bs_get_bit_position(GF_BitStream *bs);
/*!
* \brief integer writing
*
* Writes an integer on a given number of bits.
* \param bs the target bitstream
* \param value the integer to write
* \param nBits number of bits used to code the integer
*/
void gf_bs_write_int(GF_BitStream *bs, s32 value, s32 nBits);
/*!
* \brief large integer writing
*
* Writes an integer on a given number of bits greater than 32.
* \param bs the target bitstream
* \param value the large integer to write
* \param nBits number of bits used to code the integer
*/
void gf_bs_write_long_int(GF_BitStream *bs, s64 value, s32 nBits);
/*!
* \brief float writing
*
* Writes a float in IEEE 32 bits format.
* \param bs the target bitstream
* \param value the float to write
*/
void gf_bs_write_float(GF_BitStream *bs, Float value);
/*!
* \brief double writing
*
* Writes a double in IEEE 64 bits format.
* \param bs the target bitstream
* \param value the double to write
*/
void gf_bs_write_double(GF_BitStream *bs, Double value);
/*!
* \brief data writing
*
* Writes a data buffer.
* \param bs the target bitstream
* \param data the data to write
* \param nbBytes number of data bytes to write
*/
u32 gf_bs_write_data(GF_BitStream *bs, const char *data, u32 nbBytes);
/*!
* \brief align char writing
*
* Writes an integer on 8 bits starting at a byte boundary in the bitstream.
* \warning you must not use this function if the bitstream is not aligned
* \param bs the target bitstream
* \param value the char value to write
*/
void gf_bs_write_u8(GF_BitStream *bs, u32 value);
/*!
* \brief align short writing
*
* Writes an integer on 16 bits starting at a byte boundary in the bitstream.
* \warning you must not use this function if the bitstream is not aligned
* \param bs the target bitstream
* \param value the short value to write
*/
void gf_bs_write_u16(GF_BitStream *bs, u32 value);
/*!
* \brief align 24-bits integer writing
*
* Writes an integer on 24 bits starting at a byte boundary in the bitstream.
* \warning you must not use this function if the bitstream is not aligned
* \param bs the target bitstream
* \param value the integer value to write
*/
void gf_bs_write_u24(GF_BitStream *bs, u32 value);
/*!
* \brief align integer writing
*
* Writes an integer on 32 bits starting at a byte boundary in the bitstream.
* \warning you must not use this function if the bitstream is not aligned
* \param bs the target bitstream
* \param value the integer value to write
*/
void gf_bs_write_u32(GF_BitStream *bs, u32 value);
/*!
* \brief align large integer writing
*
* Writes an integer on 64 bits starting at a byte boundary in the bitstream.
* \warning you must not use this function if the bitstream is not aligned
* \param bs the target bitstream
* \param value the large integer value to write
*/
void gf_bs_write_u64(GF_BitStream *bs, u64 value);
/*!
* \brief little endian integer writing
*
* Writes an integer on 32 bits in little-endian order.
* \param bs the target bitstream
* \param value the integer value to write
*/
void gf_bs_write_u32_le(GF_BitStream *bs, u32 value);
/*!
* \brief little endian short writing
*
* Writes an integer on 16 bits in little-endian order.
* \param bs the target bitstream
* \param value the short value to write
*/
void gf_bs_write_u16_le(GF_BitStream *bs, u32 value);
/*!
* \brief write byte multiple times
*
* Writes a give byte multiple times.
* \param bs the target bitstream
* \param byte the byte value to write
* \param count the number of times the byte should be written
* \return the number of bytes written
*/
u32 gf_bs_write_byte(GF_BitStream *bs, u8 byte, u32 count);
/*!
* \brief end of bitstream management
*
* Assigns a notification callback function for end of stream signaling in read mode
* \param bs the target bitstream
* \param EndOfStream the notification function to use
* \param par opaque user data passed to the bitstream
*/
void gf_bs_set_eos_callback(GF_BitStream *bs, void (*EndOfStream)(void *par), void *par);
/*!
* \brief bitstream alignment
*
* Aligns bitstream to next byte boundary. In write mode, this will write 0 bit values until alignment.
* \param bs the target bitstream
* \return the number of bits read/written until alignment
*/
u8 gf_bs_align(GF_BitStream *bs);
/*!
* \brief capacity query
*
* Returns the number of bytes still available in the bitstream in read mode.
* \param bs the target bitstream
* \return the number of bytes still available in read mode, -1 in write modes.
*/
u64 gf_bs_available(GF_BitStream *bs);
/*!
* \brief buffer fetching
*
* Fetches the internal bitstream buffer in write mode. If a buffer was given at the bitstream construction, or if the bitstream is in read mode, this does nothing.
* \param bs the target bitstream
* \param output address of a memory block to be allocated for bitstream data.
* \param outSize set to the size of the allocated memory block.
* \note
* It is the user responsability to destroy the allocated buffer
* Once this function has been called, the internal bitstream buffer is reseted.
*/
void gf_bs_get_content(GF_BitStream *bs, char **output, u32 *outSize);
/*!
* \brief byte skipping
*
* Skips bytes in the bitstream. In Write mode, this will write the 0 integer value for memory-based bitstreams or seek the stream
for file-based bitstream.
* \param bs the target bitstream
* \param nbBytes the number of bytes to skip
*/
void gf_bs_skip_bytes(GF_BitStream *bs, u64 nbBytes);
/*!
*\brief bitstream seeking
*
*Seeks the bitstream to a given offset after the beginning of the stream. This will perform alignment of the bitstream in all modes.
*\warning Results are unpredictable if seeking beyond the bitstream end is performed.
*\param bs the target bitstream
*\param offset buffer/file offset to seek to
*/
GF_Err gf_bs_seek(GF_BitStream *bs, u64 offset);
/*!
*\brief bitstream truncation
*
*Truncates the bitstream at the current position
*\param bs the target bitstream
*/
void gf_bs_truncate(GF_BitStream *bs);
/*!
*\brief bit peeking
*
*Peeks a given number of bits (read without moving the position indicator) for read modes only.
*\param bs the target bitstream
*\param numBits the number of bits to peek
*\param byte_offset
* if set, bitstream is aligned and moved from byte_offset before peeking (byte-aligned picking)
* otherwise, bitstream is not aligned and bits are peeked from current state
*\return the integer value read
*/
u32 gf_bs_peek_bits(GF_BitStream *bs, u32 numBits, u64 byte_offset);
/*!
*\brief bit reservoir query
*
* Queries the number of bits available in read mode.
*\param bs the target bitstream
*\return number of available bits if position is in the last byte of the buffer/stream, 8 otherwise
*/
u8 gf_bs_bits_available(GF_BitStream *bs);
/*!
*\brief position query
*
*Returns the reading/writting position in the buffer/file.
*\param bs the target bitstream
*\return the read/write position of the bitstream
*/
u64 gf_bs_get_position(GF_BitStream *bs);
/*!
*\brief size query
*
*Returns the size of the associated buffer/file.
*\param bs the target bitstream
*\return the size of the bitstream
*/
u64 gf_bs_get_size(GF_BitStream *bs);
/*!
*\brief file-based size query
*
*Returns the size of a file-based bitstream and force a seek to end of file. This is used in case the file handle
*describes a file being constructed on disk while being read?
*
*\param bs the target bitstream
*\return the disk size of the associated file
*/
u64 gf_bs_get_refreshed_size(GF_BitStream *bs);
/*!
*\brief transfer content from source bitstream to destination bitstream
*
*Returns the size of the associated buffer/file.
*\param dst the target bitstream
*\param src the source bitstream. This bitstream is empty after calling teh function
*\return error if any
*/
GF_Err gf_bs_transfer(GF_BitStream *dst, GF_BitStream *src);
/*!
*\brief Flushes bitstream contet to disk
*
*Flushes bitstream contet to disk
*\param bs the target bitstream
*/
void gf_bs_flush(GF_BitStream *bs);
/*!
*\brief Reassigns FILE object for stream-based bitstreams
*
*Reassigns FILE object for stream-based bitstreams. Automatically sets the stream position to the bitstream position
*\param bs the target bitstream
*\param stream the new stream to assign
*/
void gf_bs_reassign(GF_BitStream *bs, FILE *stream);
/*! @} */
#ifdef __cplusplus
}
#endif
#endif /*_GF_BITSTREAM_H_*/