1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "media/base/bit_reader.h" 6 7 #include <algorithm> 8 9 namespace media { 10 11 BitReader::BitReader(const uint8* data, off_t size) 12 : data_(data), bytes_left_(size), num_remaining_bits_in_curr_byte_(0) { 13 DCHECK(data_ != NULL && bytes_left_ > 0); 14 15 UpdateCurrByte(); 16 } 17 18 BitReader::~BitReader() {} 19 20 bool BitReader::SkipBits(int num_bits) { 21 DCHECK_GE(num_bits, 0); 22 DVLOG_IF(0, num_bits > 100) 23 << "BitReader::SkipBits inefficient for large skips"; 24 25 // Skip any bits in the current byte waiting to be processed, then 26 // process full bytes until less than 8 bits remaining. 27 while (num_bits > 0 && num_bits > num_remaining_bits_in_curr_byte_) { 28 num_bits -= num_remaining_bits_in_curr_byte_; 29 num_remaining_bits_in_curr_byte_ = 0; 30 UpdateCurrByte(); 31 32 // If there is no more data remaining, only return true if we 33 // skipped all that were requested. 34 if (num_remaining_bits_in_curr_byte_ == 0) 35 return (num_bits == 0); 36 } 37 38 // Less than 8 bits remaining to skip. Use ReadBitsInternal to verify 39 // that the remaining bits we need exist, and adjust them as necessary 40 // for subsequent operations. 41 uint64 not_needed; 42 return ReadBitsInternal(num_bits, ¬_needed); 43 } 44 45 int BitReader::bits_available() const { 46 return 8 * bytes_left_ + num_remaining_bits_in_curr_byte_; 47 } 48 49 bool BitReader::ReadBitsInternal(int num_bits, uint64* out) { 50 DCHECK_LE(num_bits, 64); 51 52 *out = 0; 53 54 while (num_remaining_bits_in_curr_byte_ != 0 && num_bits != 0) { 55 int bits_to_take = std::min(num_remaining_bits_in_curr_byte_, num_bits); 56 57 *out <<= bits_to_take; 58 *out += curr_byte_ >> (num_remaining_bits_in_curr_byte_ - bits_to_take); 59 num_bits -= bits_to_take; 60 num_remaining_bits_in_curr_byte_ -= bits_to_take; 61 curr_byte_ &= (1 << num_remaining_bits_in_curr_byte_) - 1; 62 63 if (num_remaining_bits_in_curr_byte_ == 0) 64 UpdateCurrByte(); 65 } 66 67 return num_bits == 0; 68 } 69 70 void BitReader::UpdateCurrByte() { 71 DCHECK_EQ(num_remaining_bits_in_curr_byte_, 0); 72 73 if (bytes_left_ == 0) 74 return; 75 76 // Load a new byte and advance pointers. 77 curr_byte_ = *data_; 78 ++data_; 79 --bytes_left_; 80 num_remaining_bits_in_curr_byte_ = 8; 81 } 82 83 } // namespace media 84