Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/libtheora/bitpack.c
9903 views
1
/********************************************************************
2
* *
3
* THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
4
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7
* *
8
* THE OggTheora SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
9
* by the Xiph.Org Foundation and contributors *
10
* https://www.xiph.org/ *
11
* *
12
********************************************************************
13
14
function: packing variable sized words into an octet stream
15
16
********************************************************************/
17
#include <string.h>
18
#include <stdlib.h>
19
#include "bitpack.h"
20
21
/*We're 'MSb' endian; if we write a word but read individual bits,
22
then we'll read the MSb first.*/
23
24
void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes){
25
memset(_b,0,sizeof(*_b));
26
_b->ptr=_buf;
27
_b->stop=_buf+_bytes;
28
}
29
30
static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){
31
const unsigned char *ptr;
32
const unsigned char *stop;
33
oc_pb_window window;
34
int available;
35
unsigned shift;
36
stop=_b->stop;
37
ptr=_b->ptr;
38
window=_b->window;
39
available=_b->bits;
40
shift=OC_PB_WINDOW_SIZE-available;
41
while(7<shift&&ptr<stop){
42
shift-=8;
43
window|=(oc_pb_window)*ptr++<<shift;
44
}
45
_b->ptr=ptr;
46
available=OC_PB_WINDOW_SIZE-shift;
47
if(_bits>available){
48
if(ptr>=stop){
49
_b->eof=1;
50
available=OC_LOTS_OF_BITS;
51
}
52
else window|=*ptr>>(available&7);
53
}
54
_b->bits=available;
55
return window;
56
}
57
58
int oc_pack_look1(oc_pack_buf *_b){
59
oc_pb_window window;
60
int available;
61
window=_b->window;
62
available=_b->bits;
63
if(available<1)_b->window=window=oc_pack_refill(_b,1);
64
return window>>OC_PB_WINDOW_SIZE-1;
65
}
66
67
void oc_pack_adv1(oc_pack_buf *_b){
68
_b->window<<=1;
69
_b->bits--;
70
}
71
72
/*Here we assume that 0<=_bits&&_bits<=32.*/
73
long oc_pack_read_c(oc_pack_buf *_b,int _bits){
74
oc_pb_window window;
75
int available;
76
long result;
77
window=_b->window;
78
available=_b->bits;
79
if(_bits==0)return 0;
80
if(available<_bits){
81
window=oc_pack_refill(_b,_bits);
82
available=_b->bits;
83
}
84
result=window>>OC_PB_WINDOW_SIZE-_bits;
85
available-=_bits;
86
window<<=1;
87
window<<=_bits-1;
88
_b->window=window;
89
_b->bits=available;
90
return result;
91
}
92
93
int oc_pack_read1_c(oc_pack_buf *_b){
94
oc_pb_window window;
95
int available;
96
int result;
97
window=_b->window;
98
available=_b->bits;
99
if(available<1){
100
window=oc_pack_refill(_b,1);
101
available=_b->bits;
102
}
103
result=window>>OC_PB_WINDOW_SIZE-1;
104
available--;
105
window<<=1;
106
_b->window=window;
107
_b->bits=available;
108
return result;
109
}
110
111
long oc_pack_bytes_left(oc_pack_buf *_b){
112
if(_b->eof)return -1;
113
return _b->stop-_b->ptr+(_b->bits>>3);
114
}
115
116