1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker *
4*fb1b10abSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker */
10*fb1b10abSAndroid Build Coastguard Worker #include <stdlib.h>
11*fb1b10abSAndroid Build Coastguard Worker
12*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_config.h"
13*fb1b10abSAndroid Build Coastguard Worker
14*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/bitreader.h"
15*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/prob.h"
16*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/vpx_dsp_common.h"
17*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/mem.h"
18*fb1b10abSAndroid Build Coastguard Worker #include "vpx_mem/vpx_mem.h"
19*fb1b10abSAndroid Build Coastguard Worker #include "vpx_util/endian_inl.h"
20*fb1b10abSAndroid Build Coastguard Worker
vpx_reader_init(vpx_reader * r,const uint8_t * buffer,size_t size,vpx_decrypt_cb decrypt_cb,void * decrypt_state)21*fb1b10abSAndroid Build Coastguard Worker int vpx_reader_init(vpx_reader *r, const uint8_t *buffer, size_t size,
22*fb1b10abSAndroid Build Coastguard Worker vpx_decrypt_cb decrypt_cb, void *decrypt_state) {
23*fb1b10abSAndroid Build Coastguard Worker if (size && !buffer) {
24*fb1b10abSAndroid Build Coastguard Worker return 1;
25*fb1b10abSAndroid Build Coastguard Worker } else {
26*fb1b10abSAndroid Build Coastguard Worker r->buffer_end = buffer + size;
27*fb1b10abSAndroid Build Coastguard Worker r->buffer = buffer;
28*fb1b10abSAndroid Build Coastguard Worker r->value = 0;
29*fb1b10abSAndroid Build Coastguard Worker r->count = -8;
30*fb1b10abSAndroid Build Coastguard Worker r->range = 255;
31*fb1b10abSAndroid Build Coastguard Worker r->decrypt_cb = decrypt_cb;
32*fb1b10abSAndroid Build Coastguard Worker r->decrypt_state = decrypt_state;
33*fb1b10abSAndroid Build Coastguard Worker vpx_reader_fill(r);
34*fb1b10abSAndroid Build Coastguard Worker return vpx_read_bit(r) != 0; // marker bit
35*fb1b10abSAndroid Build Coastguard Worker }
36*fb1b10abSAndroid Build Coastguard Worker }
37*fb1b10abSAndroid Build Coastguard Worker
vpx_reader_fill(vpx_reader * r)38*fb1b10abSAndroid Build Coastguard Worker void vpx_reader_fill(vpx_reader *r) {
39*fb1b10abSAndroid Build Coastguard Worker const uint8_t *const buffer_end = r->buffer_end;
40*fb1b10abSAndroid Build Coastguard Worker const uint8_t *buffer = r->buffer;
41*fb1b10abSAndroid Build Coastguard Worker const uint8_t *buffer_start = buffer;
42*fb1b10abSAndroid Build Coastguard Worker BD_VALUE value = r->value;
43*fb1b10abSAndroid Build Coastguard Worker int count = r->count;
44*fb1b10abSAndroid Build Coastguard Worker const size_t bytes_left = buffer_end - buffer;
45*fb1b10abSAndroid Build Coastguard Worker const size_t bits_left = bytes_left * CHAR_BIT;
46*fb1b10abSAndroid Build Coastguard Worker int shift = BD_VALUE_SIZE - CHAR_BIT - (count + CHAR_BIT);
47*fb1b10abSAndroid Build Coastguard Worker
48*fb1b10abSAndroid Build Coastguard Worker if (r->decrypt_cb) {
49*fb1b10abSAndroid Build Coastguard Worker size_t n = VPXMIN(sizeof(r->clear_buffer), bytes_left);
50*fb1b10abSAndroid Build Coastguard Worker r->decrypt_cb(r->decrypt_state, buffer, r->clear_buffer, (int)n);
51*fb1b10abSAndroid Build Coastguard Worker buffer = r->clear_buffer;
52*fb1b10abSAndroid Build Coastguard Worker buffer_start = r->clear_buffer;
53*fb1b10abSAndroid Build Coastguard Worker }
54*fb1b10abSAndroid Build Coastguard Worker if (bits_left > BD_VALUE_SIZE) {
55*fb1b10abSAndroid Build Coastguard Worker const int bits = (shift & 0xfffffff8) + CHAR_BIT;
56*fb1b10abSAndroid Build Coastguard Worker BD_VALUE nv;
57*fb1b10abSAndroid Build Coastguard Worker BD_VALUE big_endian_values;
58*fb1b10abSAndroid Build Coastguard Worker memcpy(&big_endian_values, buffer, sizeof(BD_VALUE));
59*fb1b10abSAndroid Build Coastguard Worker #if SIZE_MAX == 0xffffffffffffffffULL
60*fb1b10abSAndroid Build Coastguard Worker big_endian_values = HToBE64(big_endian_values);
61*fb1b10abSAndroid Build Coastguard Worker #else
62*fb1b10abSAndroid Build Coastguard Worker big_endian_values = HToBE32(big_endian_values);
63*fb1b10abSAndroid Build Coastguard Worker #endif
64*fb1b10abSAndroid Build Coastguard Worker nv = big_endian_values >> (BD_VALUE_SIZE - bits);
65*fb1b10abSAndroid Build Coastguard Worker count += bits;
66*fb1b10abSAndroid Build Coastguard Worker buffer += (bits >> 3);
67*fb1b10abSAndroid Build Coastguard Worker value = r->value | (nv << (shift & 0x7));
68*fb1b10abSAndroid Build Coastguard Worker } else {
69*fb1b10abSAndroid Build Coastguard Worker const int bits_over = (int)(shift + CHAR_BIT - (int)bits_left);
70*fb1b10abSAndroid Build Coastguard Worker int loop_end = 0;
71*fb1b10abSAndroid Build Coastguard Worker if (bits_over >= 0) {
72*fb1b10abSAndroid Build Coastguard Worker count += LOTS_OF_BITS;
73*fb1b10abSAndroid Build Coastguard Worker loop_end = bits_over;
74*fb1b10abSAndroid Build Coastguard Worker }
75*fb1b10abSAndroid Build Coastguard Worker
76*fb1b10abSAndroid Build Coastguard Worker if (bits_over < 0 || bits_left) {
77*fb1b10abSAndroid Build Coastguard Worker while (shift >= loop_end) {
78*fb1b10abSAndroid Build Coastguard Worker count += CHAR_BIT;
79*fb1b10abSAndroid Build Coastguard Worker value |= (BD_VALUE)*buffer++ << shift;
80*fb1b10abSAndroid Build Coastguard Worker shift -= CHAR_BIT;
81*fb1b10abSAndroid Build Coastguard Worker }
82*fb1b10abSAndroid Build Coastguard Worker }
83*fb1b10abSAndroid Build Coastguard Worker }
84*fb1b10abSAndroid Build Coastguard Worker
85*fb1b10abSAndroid Build Coastguard Worker // NOTE: Variable 'buffer' may not relate to 'r->buffer' after decryption,
86*fb1b10abSAndroid Build Coastguard Worker // so we increase 'r->buffer' by the amount that 'buffer' moved, rather than
87*fb1b10abSAndroid Build Coastguard Worker // assign 'buffer' to 'r->buffer'.
88*fb1b10abSAndroid Build Coastguard Worker r->buffer += buffer - buffer_start;
89*fb1b10abSAndroid Build Coastguard Worker r->value = value;
90*fb1b10abSAndroid Build Coastguard Worker r->count = count;
91*fb1b10abSAndroid Build Coastguard Worker }
92*fb1b10abSAndroid Build Coastguard Worker
vpx_reader_find_end(vpx_reader * r)93*fb1b10abSAndroid Build Coastguard Worker const uint8_t *vpx_reader_find_end(vpx_reader *r) {
94*fb1b10abSAndroid Build Coastguard Worker // Find the end of the coded buffer
95*fb1b10abSAndroid Build Coastguard Worker while (r->count > CHAR_BIT && r->count < BD_VALUE_SIZE) {
96*fb1b10abSAndroid Build Coastguard Worker r->count -= CHAR_BIT;
97*fb1b10abSAndroid Build Coastguard Worker r->buffer--;
98*fb1b10abSAndroid Build Coastguard Worker }
99*fb1b10abSAndroid Build Coastguard Worker return r->buffer;
100*fb1b10abSAndroid Build Coastguard Worker }
101