/src/libtheora/lib/bitpack.c
Line | Count | Source (jump to first uncovered line) |
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 | 6.15k | void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes){ |
25 | 6.15k | memset(_b,0,sizeof(*_b)); |
26 | 6.15k | _b->ptr=_buf; |
27 | 6.15k | _b->stop=_buf+_bytes; |
28 | 6.15k | } |
29 | | |
30 | 319k | static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){ |
31 | 319k | const unsigned char *ptr; |
32 | 319k | const unsigned char *stop; |
33 | 319k | oc_pb_window window; |
34 | 319k | int available; |
35 | 319k | unsigned shift; |
36 | 319k | stop=_b->stop; |
37 | 319k | ptr=_b->ptr; |
38 | 319k | window=_b->window; |
39 | 319k | available=_b->bits; |
40 | 319k | shift=OC_PB_WINDOW_SIZE-available; |
41 | 2.79M | while(7<shift&&ptr<stop){ |
42 | 2.47M | shift-=8; |
43 | 2.47M | window|=(oc_pb_window)*ptr++<<shift; |
44 | 2.47M | } |
45 | 319k | _b->ptr=ptr; |
46 | 319k | available=OC_PB_WINDOW_SIZE-shift; |
47 | 319k | if(_bits>available){ |
48 | 2.43k | if(ptr>=stop){ |
49 | 2.43k | _b->eof=1; |
50 | 2.43k | available=OC_LOTS_OF_BITS; |
51 | 2.43k | } |
52 | 0 | else window|=*ptr>>(available&7); |
53 | 2.43k | } |
54 | 319k | _b->bits=available; |
55 | 319k | return window; |
56 | 319k | } |
57 | | |
58 | 0 | int oc_pack_look1(oc_pack_buf *_b){ |
59 | 0 | oc_pb_window window; |
60 | 0 | int available; |
61 | 0 | window=_b->window; |
62 | 0 | available=_b->bits; |
63 | 0 | if(available<1)_b->window=window=oc_pack_refill(_b,1); |
64 | 0 | return window>>OC_PB_WINDOW_SIZE-1; |
65 | 0 | } |
66 | | |
67 | 0 | void oc_pack_adv1(oc_pack_buf *_b){ |
68 | 0 | _b->window<<=1; |
69 | 0 | _b->bits--; |
70 | 0 | } |
71 | | |
72 | | /*Here we assume that 0<=_bits&&_bits<=32.*/ |
73 | 50.4M | long oc_pack_read_c(oc_pack_buf *_b,int _bits){ |
74 | 50.4M | oc_pb_window window; |
75 | 50.4M | int available; |
76 | 50.4M | long result; |
77 | 50.4M | window=_b->window; |
78 | 50.4M | available=_b->bits; |
79 | 50.4M | if(_bits==0)return 0; |
80 | 50.3M | if(available<_bits){ |
81 | 316k | window=oc_pack_refill(_b,_bits); |
82 | 316k | available=_b->bits; |
83 | 316k | } |
84 | 50.3M | result=window>>OC_PB_WINDOW_SIZE-_bits; |
85 | 50.3M | available-=_bits; |
86 | 50.3M | window<<=1; |
87 | 50.3M | window<<=_bits-1; |
88 | 50.3M | _b->window=window; |
89 | 50.3M | _b->bits=available; |
90 | 50.3M | return result; |
91 | 50.4M | } |
92 | | |
93 | 112k | int oc_pack_read1_c(oc_pack_buf *_b){ |
94 | 112k | oc_pb_window window; |
95 | 112k | int available; |
96 | 112k | int result; |
97 | 112k | window=_b->window; |
98 | 112k | available=_b->bits; |
99 | 112k | if(available<1){ |
100 | 2.16k | window=oc_pack_refill(_b,1); |
101 | 2.16k | available=_b->bits; |
102 | 2.16k | } |
103 | 112k | result=window>>OC_PB_WINDOW_SIZE-1; |
104 | 112k | available--; |
105 | 112k | window<<=1; |
106 | 112k | _b->window=window; |
107 | 112k | _b->bits=available; |
108 | 112k | return result; |
109 | 112k | } |
110 | | |
111 | 104k | long oc_pack_bytes_left(oc_pack_buf *_b){ |
112 | 104k | if(_b->eof)return -1; |
113 | 104k | return _b->stop-_b->ptr+(_b->bits>>3); |
114 | 104k | } |