/src/libvpx/vpx_dsp/bitreader.c
Line | Count | Source (jump to first uncovered line) |
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 | | #include <stdlib.h> |
11 | | |
12 | | #include "./vpx_config.h" |
13 | | |
14 | | #include "vpx_dsp/bitreader.h" |
15 | | #include "vpx_dsp/prob.h" |
16 | | #include "vpx_dsp/vpx_dsp_common.h" |
17 | | #include "vpx_ports/mem.h" |
18 | | #include "vpx_mem/vpx_mem.h" |
19 | | #include "vpx_util/endian_inl.h" |
20 | | |
21 | | int vpx_reader_init(vpx_reader *r, const uint8_t *buffer, size_t size, |
22 | 312k | vpx_decrypt_cb decrypt_cb, void *decrypt_state) { |
23 | 312k | if (size && !buffer) { |
24 | 0 | return 1; |
25 | 312k | } else { |
26 | 312k | r->buffer_end = buffer + size; |
27 | 312k | r->buffer = buffer; |
28 | 312k | r->value = 0; |
29 | 312k | r->count = -8; |
30 | 312k | r->range = 255; |
31 | 312k | r->decrypt_cb = decrypt_cb; |
32 | 312k | r->decrypt_state = decrypt_state; |
33 | 312k | vpx_reader_fill(r); |
34 | 312k | return vpx_read_bit(r) != 0; // marker bit |
35 | 312k | } |
36 | 312k | } |
37 | | |
38 | 5.84M | void vpx_reader_fill(vpx_reader *r) { |
39 | 5.84M | const uint8_t *const buffer_end = r->buffer_end; |
40 | 5.84M | const uint8_t *buffer = r->buffer; |
41 | 5.84M | const uint8_t *buffer_start = buffer; |
42 | 5.84M | BD_VALUE value = r->value; |
43 | 5.84M | int count = r->count; |
44 | 5.84M | const size_t bytes_left = buffer_end - buffer; |
45 | 5.84M | const size_t bits_left = bytes_left * CHAR_BIT; |
46 | 5.84M | int shift = BD_VALUE_SIZE - CHAR_BIT - (count + CHAR_BIT); |
47 | | |
48 | 5.84M | if (r->decrypt_cb) { |
49 | 0 | size_t n = VPXMIN(sizeof(r->clear_buffer), bytes_left); |
50 | 0 | r->decrypt_cb(r->decrypt_state, buffer, r->clear_buffer, (int)n); |
51 | 0 | buffer = r->clear_buffer; |
52 | 0 | buffer_start = r->clear_buffer; |
53 | 0 | } |
54 | 5.84M | if (bits_left > BD_VALUE_SIZE) { |
55 | 5.71M | const int bits = (shift & 0xfffffff8) + CHAR_BIT; |
56 | 5.71M | BD_VALUE nv; |
57 | 5.71M | BD_VALUE big_endian_values; |
58 | 5.71M | memcpy(&big_endian_values, buffer, sizeof(BD_VALUE)); |
59 | 5.71M | #if SIZE_MAX == 0xffffffffffffffffULL |
60 | 5.71M | big_endian_values = HToBE64(big_endian_values); |
61 | | #else |
62 | | big_endian_values = HToBE32(big_endian_values); |
63 | | #endif |
64 | 5.71M | nv = big_endian_values >> (BD_VALUE_SIZE - bits); |
65 | 5.71M | count += bits; |
66 | 5.71M | buffer += (bits >> 3); |
67 | 5.71M | value = r->value | (nv << (shift & 0x7)); |
68 | 5.71M | } else { |
69 | 129k | const int bits_over = (int)(shift + CHAR_BIT - (int)bits_left); |
70 | 129k | int loop_end = 0; |
71 | 129k | if (bits_over >= 0) { |
72 | 124k | count += LOTS_OF_BITS; |
73 | 124k | loop_end = bits_over; |
74 | 124k | } |
75 | | |
76 | 129k | if (bits_over < 0 || bits_left) { |
77 | 733k | while (shift >= loop_end) { |
78 | 603k | count += CHAR_BIT; |
79 | 603k | value |= (BD_VALUE)*buffer++ << shift; |
80 | 603k | shift -= CHAR_BIT; |
81 | 603k | } |
82 | 129k | } |
83 | 129k | } |
84 | | |
85 | | // NOTE: Variable 'buffer' may not relate to 'r->buffer' after decryption, |
86 | | // so we increase 'r->buffer' by the amount that 'buffer' moved, rather than |
87 | | // assign 'buffer' to 'r->buffer'. |
88 | 5.84M | r->buffer += buffer - buffer_start; |
89 | 5.84M | r->value = value; |
90 | 5.84M | r->count = count; |
91 | 5.84M | } |
92 | | |
93 | 117k | const uint8_t *vpx_reader_find_end(vpx_reader *r) { |
94 | | // Find the end of the coded buffer |
95 | 506k | while (r->count > CHAR_BIT && r->count < BD_VALUE_SIZE) { |
96 | 389k | r->count -= CHAR_BIT; |
97 | 389k | r->buffer--; |
98 | 389k | } |
99 | 117k | return r->buffer; |
100 | 117k | } |