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// 34void 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// 44uint32_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 69uint8_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 93uint8_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// 111uint32_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// 119uint32_t BitBufferPeekOne (BitBuffer * bits) 120{ 121 return ((bits->cur [0] >> (7 - bits->bitIndex)) & 1) ; 122} 123 124// BitBufferUnpackBERSize 125// 126uint32_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// 139uint32_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// 150void 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// 164void 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// 176void 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// 214void 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 253void 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 263