Imported Upstream version 1.0.26
[platform/upstream/libsndfile.git] / src / ALAC / ALACBitUtilities.c
1 /*
2  * Copyright (c) 2011 Apple Inc. All rights reserved.
3  *
4  * @APPLE_APACHE_LICENSE_HEADER_START@
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License") ;
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *       http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * @APPLE_APACHE_LICENSE_HEADER_END@
19  */
20
21 /*=============================================================================
22         File:           ALACBitUtilities.c
23
24         $NoKeywords: $
25 =============================================================================*/
26
27 #include <stdio.h>
28 #include "ALACBitUtilities.h"
29
30 #define PRAGMA_MARK 0
31
32 // BitBufferInit
33 //
34 void BitBufferInit (BitBuffer * bits, uint8_t * buffer, uint32_t byteSize)
35 {
36         bits->cur               = buffer ;
37         bits->end               = bits->cur + byteSize ;
38         bits->bitIndex  = 0 ;
39         bits->byteSize  = byteSize ;
40 }
41
42 // BitBufferRead
43 //
44 uint32_t BitBufferRead (BitBuffer * bits, uint8_t numBits)
45 {
46         uint32_t                returnBits ;
47
48         //Assert (numBits <= 16) ;
49
50         returnBits = ((uint32_t) bits->cur [0] << 16) | ((uint32_t) bits->cur [1] << 8) | ((uint32_t) bits->cur [2]) ;
51         returnBits = returnBits << bits->bitIndex ;
52         returnBits &= 0x00FFFFFF ;
53
54         bits->bitIndex += numBits ;
55
56         returnBits = returnBits >> (24 - numBits) ;
57
58         bits->cur               += (bits->bitIndex >> 3) ;
59         bits->bitIndex  &= 7 ;
60
61         //Assert (bits->cur <= bits->end) ;
62
63         return returnBits ;
64 }
65
66 // BitBufferReadSmall
67 //
68 // Reads up to 8 bits
69 uint8_t BitBufferReadSmall (BitBuffer * bits, uint8_t numBits)
70 {
71         uint16_t                returnBits ;
72
73         //Assert (numBits <= 8) ;
74
75         returnBits = (bits->cur [0] << 8) | bits->cur [1] ;
76         returnBits = returnBits << bits->bitIndex ;
77
78         bits->bitIndex += numBits ;
79
80         returnBits = returnBits >> (16 - numBits) ;
81
82         bits->cur               += (bits->bitIndex >> 3) ;
83         bits->bitIndex  &= 7 ;
84
85         //Assert (bits->cur <= bits->end) ;
86
87         return (uint8_t) returnBits ;
88 }
89
90 // BitBufferReadOne
91 //
92 // Reads one byte
93 uint8_t BitBufferReadOne (BitBuffer * bits)
94 {
95         uint8_t         returnBits ;
96
97         returnBits = (bits->cur [0] >> (7 - bits->bitIndex)) & 1 ;
98
99         bits->bitIndex++ ;
100
101         bits->cur               += (bits->bitIndex >> 3) ;
102         bits->bitIndex  &= 7 ;
103
104         //Assert (bits->cur <= bits->end) ;
105
106         return returnBits ;
107 }
108
109 // BitBufferPeek
110 //
111 uint32_t BitBufferPeek (BitBuffer * bits, uint8_t numBits)
112 {
113         return ((((((uint32_t) bits->cur [0] << 16) | ((uint32_t) bits->cur [1] << 8) |
114                         ((uint32_t) bits->cur [2])) << bits->bitIndex) & 0x00FFFFFF) >> (24 - numBits)) ;
115 }
116
117 // BitBufferPeekOne
118 //
119 uint32_t BitBufferPeekOne (BitBuffer * bits)
120 {
121         return ((bits->cur [0] >> (7 - bits->bitIndex)) & 1) ;
122 }
123
124 // BitBufferUnpackBERSize
125 //
126 uint32_t BitBufferUnpackBERSize (BitBuffer * bits)
127 {
128         uint32_t                size ;
129         uint8_t         tmp ;
130
131         for (size = 0, tmp = 0x80u ; tmp &= 0x80u ; size = (size << 7u) | (tmp & 0x7fu))
132                 tmp = (uint8_t) BitBufferReadSmall (bits, 8) ;
133
134         return size ;
135 }
136
137 // BitBufferGetPosition
138 //
139 uint32_t BitBufferGetPosition (BitBuffer * bits)
140 {
141         uint8_t *               begin ;
142
143         begin = bits->end - bits->byteSize ;
144
145         return ((uint32_t) (bits->cur - begin) * 8) + bits->bitIndex ;
146 }
147
148 // BitBufferByteAlign
149 //
150 void BitBufferByteAlign (BitBuffer * bits, int32_t addZeros)
151 {
152         // align bit buffer to next byte boundary, writing zeros if requested
153         if (bits->bitIndex == 0)
154                 return ;
155
156         if (addZeros)
157                 BitBufferWrite (bits, 0, 8 - bits->bitIndex) ;
158         else
159                 BitBufferAdvance (bits, 8 - bits->bitIndex) ;
160 }
161
162 // BitBufferAdvance
163 //
164 void BitBufferAdvance (BitBuffer * bits, uint32_t numBits)
165 {
166         if (numBits)
167         {
168                 bits->bitIndex += numBits ;
169                 bits->cur += (bits->bitIndex >> 3) ;
170                 bits->bitIndex &= 7 ;
171         }
172 }
173
174 // BitBufferRewind
175 //
176 void BitBufferRewind (BitBuffer * bits, uint32_t numBits)
177 {
178         uint32_t        numBytes ;
179
180         if (numBits == 0)
181                 return ;
182
183         if (bits->bitIndex >= numBits)
184         {
185                 bits->bitIndex -= numBits ;
186                 return ;
187         }
188
189         numBits -= bits->bitIndex ;
190         bits->bitIndex = 0 ;
191
192         numBytes        = numBits / 8 ;
193         numBits         = numBits % 8 ;
194
195         bits->cur -= numBytes ;
196
197         if (numBits > 0)
198         {
199                 bits->bitIndex = 8 - numBits ;
200                 bits->cur-- ;
201         }
202
203         if (bits->cur < (bits->end - bits->byteSize))
204         {
205                 //DebugCMsg ("BitBufferRewind: Rewound too far.") ;
206
207                 bits->cur               = (bits->end - bits->byteSize) ;
208                 bits->bitIndex  = 0 ;
209         }
210 }
211
212 // BitBufferWrite
213 //
214 void BitBufferWrite (BitBuffer * bits, uint32_t bitValues, uint32_t numBits)
215 {
216         uint32_t                                invBitIndex ;
217
218         RequireAction (bits != NULL, return ;) ;
219         RequireActionSilent (numBits > 0, return ;) ;
220
221         invBitIndex = 8 - bits->bitIndex ;
222
223         while (numBits > 0)
224         {
225                 uint32_t                tmp ;
226                 uint8_t         shift ;
227                 uint8_t         mask ;
228                 uint32_t                curNum ;
229
230                 curNum = MIN (invBitIndex, numBits) ;
231
232                 tmp = bitValues >> (numBits - curNum) ;
233
234                 shift = (uint8_t) (invBitIndex - curNum) ;
235                 mask = 0xffu >> (8 - curNum) ;          // must be done in two steps to avoid compiler sequencing ambiguity
236                 mask <<= shift ;
237
238                 bits->cur [0] = (bits->cur [0] & ~mask) | (((uint8_t) tmp << shift) & mask) ;
239                 numBits -= curNum ;
240
241                 // increment to next byte if need be
242                 invBitIndex -= curNum ;
243                 if (invBitIndex == 0)
244                 {
245                         invBitIndex = 8 ;
246                         bits->cur++ ;
247                 }
248         }
249
250         bits->bitIndex = 8 - invBitIndex ;
251 }
252
253 void    BitBufferReset (BitBuffer * bits)
254 //void BitBufferInit (BitBuffer * bits, uint8_t * buffer, uint32_t byteSize)
255 {
256         bits->cur = bits->end - bits->byteSize ;
257         bits->bitIndex = 0 ;
258 }
259
260 #if PRAGMA_MARK
261 #pragma mark -
262 #endif