/* * 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_*/