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