1/* 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "vpx_ports/mem.h" 12#include "vpx_mem/vpx_mem.h" 13 14#include "vp9/decoder/vp9_reader.h" 15 16// This is meant to be a large, positive constant that can still be efficiently 17// loaded as an immediate (on platforms like ARM, for example). 18// Even relatively modest values like 100 would work fine. 19#define LOTS_OF_BITS 0x40000000 20 21int vp9_reader_init(vp9_reader *r, 22 const uint8_t *buffer, 23 size_t size, 24 vpx_decrypt_cb decrypt_cb, 25 void *decrypt_state) { 26 if (size && !buffer) { 27 return 1; 28 } else { 29 r->buffer_end = buffer + size; 30 r->buffer = buffer; 31 r->value = 0; 32 r->count = -8; 33 r->range = 255; 34 r->decrypt_cb = decrypt_cb; 35 r->decrypt_state = decrypt_state; 36 vp9_reader_fill(r); 37 return vp9_read_bit(r) != 0; // marker bit 38 } 39} 40 41void vp9_reader_fill(vp9_reader *r) { 42 const uint8_t *const buffer_end = r->buffer_end; 43 const uint8_t *buffer = r->buffer; 44 const uint8_t *buffer_start = buffer; 45 BD_VALUE value = r->value; 46 int count = r->count; 47 int shift = BD_VALUE_SIZE - CHAR_BIT - (count + CHAR_BIT); 48 int loop_end = 0; 49 const size_t bytes_left = buffer_end - buffer; 50 const size_t bits_left = bytes_left * CHAR_BIT; 51 const int x = (int)(shift + CHAR_BIT - bits_left); 52 53 if (r->decrypt_cb) { 54 size_t n = MIN(sizeof(r->clear_buffer), bytes_left); 55 r->decrypt_cb(r->decrypt_state, buffer, r->clear_buffer, (int)n); 56 buffer = r->clear_buffer; 57 buffer_start = r->clear_buffer; 58 } 59 60 if (x >= 0) { 61 count += LOTS_OF_BITS; 62 loop_end = x; 63 } 64 65 if (x < 0 || bits_left) { 66 while (shift >= loop_end) { 67 count += CHAR_BIT; 68 value |= (BD_VALUE)*buffer++ << shift; 69 shift -= CHAR_BIT; 70 } 71 } 72 73 // NOTE: Variable 'buffer' may not relate to 'r->buffer' after decryption, 74 // so we increase 'r->buffer' by the amount that 'buffer' moved, rather than 75 // assign 'buffer' to 'r->buffer'. 76 r->buffer += buffer - buffer_start; 77 r->value = value; 78 r->count = count; 79} 80 81const uint8_t *vp9_reader_find_end(vp9_reader *r) { 82 // Find the end of the coded buffer 83 while (r->count > CHAR_BIT && r->count < BD_VALUE_SIZE) { 84 r->count -= CHAR_BIT; 85 r->buffer--; 86 } 87 return r->buffer; 88} 89 90int vp9_reader_has_error(vp9_reader *r) { 91 // Check if we have reached the end of the buffer. 92 // 93 // Variable 'count' stores the number of bits in the 'value' buffer, minus 94 // 8. The top byte is part of the algorithm, and the remainder is buffered 95 // to be shifted into it. So if count == 8, the top 16 bits of 'value' are 96 // occupied, 8 for the algorithm and 8 in the buffer. 97 // 98 // When reading a byte from the user's buffer, count is filled with 8 and 99 // one byte is filled into the value buffer. When we reach the end of the 100 // data, count is additionally filled with LOTS_OF_BITS. So when 101 // count == LOTS_OF_BITS - 1, the user's data has been exhausted. 102 // 103 // 1 if we have tried to decode bits after the end of stream was encountered. 104 // 0 No error. 105 return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS; 106} 107