mirror of https://github.com/mpv-player/mpv
145 lines
3.4 KiB
C
145 lines
3.4 KiB
C
/********************************************************************
|
|
* *
|
|
* THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
|
|
* *
|
|
* THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
|
|
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
|
|
* ALL REDISTRIBUTION RIGHTS RESERVED. *
|
|
* *
|
|
********************************************************************
|
|
|
|
function: packing variable sized words into an octet stream
|
|
|
|
********************************************************************/
|
|
|
|
/* We're 'LSb' endian; if we write a word but read individual bits,
|
|
then we'll read the lsb first */
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "ogg.h"
|
|
|
|
#define BUFFER_INCREMENT 256
|
|
|
|
static unsigned long mask[]=
|
|
{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
|
|
0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
|
|
0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
|
|
0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
|
|
0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
|
|
0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
|
|
0x3fffffff,0x7fffffff,0xffffffff };
|
|
|
|
void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){
|
|
memset(b,0,sizeof(*b));
|
|
b->buffer=b->ptr=buf;
|
|
b->storage=bytes;
|
|
}
|
|
|
|
/* Read in bits without advancing the bitptr; bits <= 32 */
|
|
long oggpack_look(oggpack_buffer *b,int bits){
|
|
unsigned long ret;
|
|
unsigned long m=mask[bits];
|
|
|
|
bits+=b->endbit;
|
|
|
|
if(b->endbyte+4>=b->storage){
|
|
/* not the main path */
|
|
if(b->endbyte*8+bits>b->storage*8)return(-1);
|
|
}
|
|
|
|
ret=b->ptr[0]>>b->endbit;
|
|
if(bits>8){
|
|
ret|=b->ptr[1]<<(8-b->endbit);
|
|
if(bits>16){
|
|
ret|=b->ptr[2]<<(16-b->endbit);
|
|
if(bits>24){
|
|
ret|=b->ptr[3]<<(24-b->endbit);
|
|
if(bits>32 && b->endbit)
|
|
ret|=b->ptr[4]<<(32-b->endbit);
|
|
}
|
|
}
|
|
}
|
|
return(m&ret);
|
|
}
|
|
|
|
long oggpack_look1(oggpack_buffer *b){
|
|
if(b->endbyte>=b->storage)return(-1);
|
|
return((b->ptr[0]>>b->endbit)&1);
|
|
}
|
|
|
|
void oggpack_adv(oggpack_buffer *b,int bits){
|
|
bits+=b->endbit;
|
|
b->ptr+=bits/8;
|
|
b->endbyte+=bits/8;
|
|
b->endbit=bits&7;
|
|
}
|
|
|
|
void oggpack_adv1(oggpack_buffer *b){
|
|
if(++(b->endbit)>7){
|
|
b->endbit=0;
|
|
b->ptr++;
|
|
b->endbyte++;
|
|
}
|
|
}
|
|
|
|
/* bits <= 32 */
|
|
long oggpack_read(oggpack_buffer *b,int bits){
|
|
unsigned long ret;
|
|
unsigned long m=mask[bits];
|
|
|
|
bits+=b->endbit;
|
|
|
|
if(b->endbyte+4>=b->storage){
|
|
/* not the main path */
|
|
ret=-1UL;
|
|
if(b->endbyte*8+bits>b->storage*8)goto overflow;
|
|
}
|
|
|
|
ret=b->ptr[0]>>b->endbit;
|
|
if(bits>8){
|
|
ret|=b->ptr[1]<<(8-b->endbit);
|
|
if(bits>16){
|
|
ret|=b->ptr[2]<<(16-b->endbit);
|
|
if(bits>24){
|
|
ret|=b->ptr[3]<<(24-b->endbit);
|
|
if(bits>32 && b->endbit){
|
|
ret|=b->ptr[4]<<(32-b->endbit);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ret&=m;
|
|
|
|
overflow:
|
|
|
|
b->ptr+=bits/8;
|
|
b->endbyte+=bits/8;
|
|
b->endbit=bits&7;
|
|
return(ret);
|
|
}
|
|
|
|
long oggpack_read1(oggpack_buffer *b){
|
|
unsigned long ret;
|
|
|
|
if(b->endbyte>=b->storage){
|
|
/* not the main path */
|
|
ret=-1UL;
|
|
goto overflow;
|
|
}
|
|
|
|
ret=(b->ptr[0]>>b->endbit)&1;
|
|
|
|
overflow:
|
|
|
|
b->endbit++;
|
|
if(b->endbit>7){
|
|
b->endbit=0;
|
|
b->ptr++;
|
|
b->endbyte++;
|
|
}
|
|
return(ret);
|
|
}
|
|
|
|
#undef BUFFER_INCREMENT
|