1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*
2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc.
3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License");
5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License.
6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at
7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **     http://www.apache.org/licenses/LICENSE-2.0
9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software
11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS,
12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and
14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License.
15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */
16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*******************************************************************************
17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	File:		bitbuffer.c
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Content:	Bit Buffer Management functions
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
21956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*******************************************************************************/
22956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
23956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "bitbuffer.h"
24956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
25956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
27956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: updateBitBufWordPtr
28956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  update Bit Buffer pointer
29956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void updateBitBufWordPtr(HANDLE_BIT_BUF hBitBuf,
32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                UWord8 **pBitBufWord,
33956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                                Word16   cnt)
34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
35b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  *pBitBufWord += cnt;
36b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if(*pBitBufWord > hBitBuf->pBitBufEnd) {
39b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    *pBitBufWord -= (hBitBuf->pBitBufEnd - hBitBuf->pBitBufBase + 1);
40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
41b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if(*pBitBufWord < hBitBuf->pBitBufBase) {
43b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard    *pBitBufWord += (hBitBuf->pBitBufEnd - hBitBuf->pBitBufBase + 1);
44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: CreateBitBuffer
51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  create and init Bit Buffer Management
52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongHANDLE_BIT_BUF CreateBitBuffer(HANDLE_BIT_BUF hBitBuf,
55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               UWord8 *pBitBufBase,
56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                               Word16  bitBufSize)
57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  assert(bitBufSize*8 <= 32768);
59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
60b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->pBitBufBase = pBitBufBase;
61b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->pBitBufEnd  = pBitBufBase + bitBufSize - 1;
62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
63b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->pWriteNext  = pBitBufBase;
64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  hBitBuf->cache       = 0;
66b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
67b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->wBitPos     = 0;
68b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->cntBits     = 0;
69b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
70b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->size        = (bitBufSize << 3);
71b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->isValid     = 1;
72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return hBitBuf;
74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: DeleteBitBuffer
79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  uninit Bit Buffer Management
80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid DeleteBitBuffer(HANDLE_BIT_BUF *hBitBuf)
83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard  if(*hBitBuf)
85b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	(*hBitBuf)->isValid = 0;
86b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  *hBitBuf = NULL;
87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: ResetBitBuf
92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  reset Bit Buffer Management
93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid ResetBitBuf(HANDLE_BIT_BUF hBitBuf,
96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                 UWord8 *pBitBufBase,
97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                 Word16  bitBufSize)
98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
99b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->pBitBufBase = pBitBufBase;
100b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->pBitBufEnd  = pBitBufBase + bitBufSize - 1;
101b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
103b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->pWriteNext  = pBitBufBase;
104b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
105b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->wBitPos     = 0;
106b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->cntBits     = 0;
107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  hBitBuf->cache	   = 0;
109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: CopyBitBuf
114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  copy Bit Buffer Management
115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid CopyBitBuf(HANDLE_BIT_BUF hBitBufSrc,
118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                HANDLE_BIT_BUF hBitBufDst)
119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
120b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  *hBitBufDst = *hBitBufSrc;
121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
124956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
125956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: GetBitsAvail
126956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  get available bits
127956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
128956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 GetBitsAvail(HANDLE_BIT_BUF hBitBuf)
130956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
131956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return hBitBuf->cntBits;
132956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
133956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/*****************************************************************************
135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: WriteBits
137956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description:  write bits to the buffer
138956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*
139956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/
140956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord16 WriteBits(HANDLE_BIT_BUF hBitBuf,
1415e9afe434d8207fb0af6e191cca671ab74cfe878Martin Storsjo                 UWord32 writeValue,
142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong                 Word16 noBitsToWrite)
143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{
144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  Word16 wBitPos;
145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  assert(noBitsToWrite <= (Word16)sizeof(Word32)*8);
147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  if(noBitsToWrite == 0)
149956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  return noBitsToWrite;
150956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
151b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  hBitBuf->cntBits += noBitsToWrite;
152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong
153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  wBitPos = hBitBuf->wBitPos;
154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  wBitPos += noBitsToWrite;
1553989d5c21ce6d1f3492c9e5484d610d5d66abd9eMartin Storsjo  writeValue &= ~(0xffffffff << noBitsToWrite); // Mask out everything except the lowest noBitsToWrite bits
156b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  writeValue <<= 32 - wBitPos;
157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  writeValue |= hBitBuf->cache;
158b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
159b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard  while (wBitPos >= 8)
160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  {
161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  UWord8 tmp;
162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  tmp = (UWord8)((writeValue >> 24) & 0xFF);
163b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
164b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	  *hBitBuf->pWriteNext++ = tmp;
165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  writeValue <<= 8;
166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong	  wBitPos -= 8;
167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  }
168b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  hBitBuf->wBitPos = wBitPos;
170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  hBitBuf->cache = writeValue;
171b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard
172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong  return noBitsToWrite;
173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong}
174