|
Packit |
5e46da |
/*****************************************************************************
|
|
Packit |
5e46da |
* bits.h : Bit handling helpers
|
|
Packit |
5e46da |
*****************************************************************************
|
|
Packit |
5e46da |
* Copyright (C) 2003 the VideoLAN team
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* This library is free software; you can redistribute it and/or
|
|
Packit |
5e46da |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
5e46da |
* License as published by the Free Software Foundation; either
|
|
Packit |
5e46da |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
5e46da |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
5e46da |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
5e46da |
* Lesser General Public License for more details.
|
|
Packit |
5e46da |
*
|
|
Packit |
5e46da |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
5e46da |
* License along with this library. If not, see
|
|
Packit |
5e46da |
* <http://www.gnu.org/licenses/>.
|
|
Packit |
5e46da |
*****************************************************************************/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#ifndef BD_BITS_H
|
|
Packit |
5e46da |
#define BD_BITS_H
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include "util/attributes.h"
|
|
Packit |
5e46da |
#include "file/filesystem.h" // BD_FILE_H
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#include <stdint.h>
|
|
Packit |
5e46da |
#include <stddef.h> // size_t
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
/**
|
|
Packit |
5e46da |
* \file
|
|
Packit |
5e46da |
* This file defines functions, structures for handling streams of bits
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#define BF_BUF_SIZE (1024*32)
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
typedef struct {
|
|
Packit |
5e46da |
const uint8_t *p_start;
|
|
Packit |
5e46da |
const uint8_t *p;
|
|
Packit |
5e46da |
const uint8_t *p_end;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
int i_left; /* i_count number of available bits */
|
|
Packit |
5e46da |
} BITBUFFER;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
typedef struct {
|
|
Packit |
5e46da |
BD_FILE_H *fp;
|
|
Packit |
5e46da |
uint8_t buf[BF_BUF_SIZE];
|
|
Packit |
5e46da |
BITBUFFER bb;
|
|
Packit |
5e46da |
int64_t pos; /* file offset of buffer start (buf[0]) */
|
|
Packit |
5e46da |
int64_t end; /* size of file */
|
|
Packit |
5e46da |
size_t size; /* bytes in buf */
|
|
Packit |
5e46da |
} BITSTREAM;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
BD_PRIVATE void bb_init( BITBUFFER *bb, const uint8_t *p_data, size_t i_data );
|
|
Packit |
5e46da |
BD_PRIVATE int bs_init( BITSTREAM *bs, BD_FILE_H *fp ) BD_USED;
|
|
Packit |
5e46da |
BD_PRIVATE void bb_seek( BITBUFFER *bb, int64_t off, int whence);
|
|
Packit |
5e46da |
//BD_PRIVATE void bs_seek( BITSTREAM *bs, int64_t off, int whence);
|
|
Packit |
5e46da |
//BD_PRIVATE void bb_seek_byte( BITBUFFER *bb, int64_t off);
|
|
Packit |
5e46da |
BD_PRIVATE int bs_seek_byte( BITSTREAM *s, int64_t off) BD_USED;
|
|
Packit |
5e46da |
BD_PRIVATE void bb_skip( BITBUFFER *bb, size_t i_count );
|
|
Packit |
5e46da |
BD_PRIVATE void bs_skip( BITSTREAM *bs, size_t i_count ); /* note: i_count must be less than BF_BUF_SIZE */
|
|
Packit |
5e46da |
BD_PRIVATE uint32_t bb_read( BITBUFFER *bb, int i_count );
|
|
Packit |
5e46da |
BD_PRIVATE uint32_t bs_read( BITSTREAM *bs, int i_count );
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static inline int64_t bb_pos( const BITBUFFER *bb )
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
return 8 * ( bb->p - bb->p_start ) + 8 - bb->i_left;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static inline int64_t bs_pos( const BITSTREAM *bs )
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
return bs->pos * 8 + bb_pos(&bs->bb);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static inline int64_t bs_end( const BITSTREAM *bs )
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
return bs->end * 8;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static inline int bb_eof( const BITBUFFER *bb )
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
return bb->p >= bb->p_end ? 1: 0 ;
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
/*
|
|
Packit |
5e46da |
static inline int bs_eof( const BITSTREAM *bs )
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
return file_eof(bs->fp) && bb_eof(&bs->bb);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
*/
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static inline int64_t bs_avail( const BITSTREAM *bs )
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
return bs_end(bs) - bs_pos(bs);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static inline void bb_read_bytes( BITBUFFER *bb, uint8_t *buf, int i_count )
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
int ii;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
for (ii = 0; ii < i_count; ii++) {
|
|
Packit |
5e46da |
buf[ii] = bb_read(bb, 8);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static inline void bs_read_bytes( BITSTREAM *s, uint8_t *buf, int i_count )
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
int ii;
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
for (ii = 0; ii < i_count; ii++) {
|
|
Packit |
5e46da |
buf[ii] = bs_read(s, 8);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
static inline void bs_read_string( BITSTREAM *s, char *buf, int i_count )
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
bs_read_bytes(s, (uint8_t*)buf, i_count);
|
|
Packit |
5e46da |
buf[i_count] = '\0';
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static inline uint32_t bb_show( BITBUFFER *bb, int i_count )
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
BITBUFFER bb_tmp = *bb;
|
|
Packit |
5e46da |
return bb_read( &bb_tmp, i_count );
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static inline int bb_is_align( BITBUFFER *bb, uint32_t mask )
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
int64_t off = bb_pos(bb);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return !(off & mask);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
static inline int bs_is_align( BITSTREAM *s, uint32_t mask )
|
|
Packit |
5e46da |
{
|
|
Packit |
5e46da |
int64_t off = bs_pos(s);
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
return !(off & mask);
|
|
Packit |
5e46da |
}
|
|
Packit |
5e46da |
|
|
Packit |
5e46da |
#endif
|