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
11*fb1b10abSAndroid Build Coastguard Worker #include "dboolhuff.h"
12*fb1b10abSAndroid Build Coastguard Worker #include "vp8/common/common.h"
13*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/vpx_dsp_common.h"
14*fb1b10abSAndroid Build Coastguard Worker
vp8dx_start_decode(BOOL_DECODER * br,const unsigned char * source,unsigned int source_sz,vpx_decrypt_cb decrypt_cb,void * decrypt_state)15*fb1b10abSAndroid Build Coastguard Worker int vp8dx_start_decode(BOOL_DECODER *br, const unsigned char *source,
16*fb1b10abSAndroid Build Coastguard Worker unsigned int source_sz, vpx_decrypt_cb decrypt_cb,
17*fb1b10abSAndroid Build Coastguard Worker void *decrypt_state) {
18*fb1b10abSAndroid Build Coastguard Worker if (source_sz && !source) return 1;
19*fb1b10abSAndroid Build Coastguard Worker
20*fb1b10abSAndroid Build Coastguard Worker // To simplify calling code this fuction can be called with |source| == null
21*fb1b10abSAndroid Build Coastguard Worker // and |source_sz| == 0. This and vp8dx_bool_decoder_fill() are essentially
22*fb1b10abSAndroid Build Coastguard Worker // no-ops in this case.
23*fb1b10abSAndroid Build Coastguard Worker // Work around a ubsan warning with a ternary to avoid adding 0 to null.
24*fb1b10abSAndroid Build Coastguard Worker br->user_buffer_end = source ? source + source_sz : source;
25*fb1b10abSAndroid Build Coastguard Worker br->user_buffer = source;
26*fb1b10abSAndroid Build Coastguard Worker br->value = 0;
27*fb1b10abSAndroid Build Coastguard Worker br->count = -8;
28*fb1b10abSAndroid Build Coastguard Worker br->range = 255;
29*fb1b10abSAndroid Build Coastguard Worker br->decrypt_cb = decrypt_cb;
30*fb1b10abSAndroid Build Coastguard Worker br->decrypt_state = decrypt_state;
31*fb1b10abSAndroid Build Coastguard Worker
32*fb1b10abSAndroid Build Coastguard Worker /* Populate the buffer */
33*fb1b10abSAndroid Build Coastguard Worker vp8dx_bool_decoder_fill(br);
34*fb1b10abSAndroid Build Coastguard Worker
35*fb1b10abSAndroid Build Coastguard Worker return 0;
36*fb1b10abSAndroid Build Coastguard Worker }
37*fb1b10abSAndroid Build Coastguard Worker
vp8dx_bool_decoder_fill(BOOL_DECODER * br)38*fb1b10abSAndroid Build Coastguard Worker void vp8dx_bool_decoder_fill(BOOL_DECODER *br) {
39*fb1b10abSAndroid Build Coastguard Worker const unsigned char *bufptr = br->user_buffer;
40*fb1b10abSAndroid Build Coastguard Worker VP8_BD_VALUE value = br->value;
41*fb1b10abSAndroid Build Coastguard Worker int count = br->count;
42*fb1b10abSAndroid Build Coastguard Worker int shift = VP8_BD_VALUE_SIZE - CHAR_BIT - (count + CHAR_BIT);
43*fb1b10abSAndroid Build Coastguard Worker size_t bytes_left = br->user_buffer_end - bufptr;
44*fb1b10abSAndroid Build Coastguard Worker size_t bits_left = bytes_left * CHAR_BIT;
45*fb1b10abSAndroid Build Coastguard Worker int x = shift + CHAR_BIT - (int)bits_left;
46*fb1b10abSAndroid Build Coastguard Worker int loop_end = 0;
47*fb1b10abSAndroid Build Coastguard Worker unsigned char decrypted[sizeof(VP8_BD_VALUE) + 1];
48*fb1b10abSAndroid Build Coastguard Worker
49*fb1b10abSAndroid Build Coastguard Worker if (br->decrypt_cb) {
50*fb1b10abSAndroid Build Coastguard Worker size_t n = VPXMIN(sizeof(decrypted), bytes_left);
51*fb1b10abSAndroid Build Coastguard Worker br->decrypt_cb(br->decrypt_state, bufptr, decrypted, (int)n);
52*fb1b10abSAndroid Build Coastguard Worker bufptr = decrypted;
53*fb1b10abSAndroid Build Coastguard Worker }
54*fb1b10abSAndroid Build Coastguard Worker
55*fb1b10abSAndroid Build Coastguard Worker if (x >= 0) {
56*fb1b10abSAndroid Build Coastguard Worker count += VP8_LOTS_OF_BITS;
57*fb1b10abSAndroid Build Coastguard Worker loop_end = x;
58*fb1b10abSAndroid Build Coastguard Worker }
59*fb1b10abSAndroid Build Coastguard Worker
60*fb1b10abSAndroid Build Coastguard Worker if (x < 0 || bits_left) {
61*fb1b10abSAndroid Build Coastguard Worker while (shift >= loop_end) {
62*fb1b10abSAndroid Build Coastguard Worker count += CHAR_BIT;
63*fb1b10abSAndroid Build Coastguard Worker value |= (VP8_BD_VALUE)*bufptr << shift;
64*fb1b10abSAndroid Build Coastguard Worker ++bufptr;
65*fb1b10abSAndroid Build Coastguard Worker ++br->user_buffer;
66*fb1b10abSAndroid Build Coastguard Worker shift -= CHAR_BIT;
67*fb1b10abSAndroid Build Coastguard Worker }
68*fb1b10abSAndroid Build Coastguard Worker }
69*fb1b10abSAndroid Build Coastguard Worker
70*fb1b10abSAndroid Build Coastguard Worker br->value = value;
71*fb1b10abSAndroid Build Coastguard Worker br->count = count;
72*fb1b10abSAndroid Build Coastguard Worker }
73