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