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 #ifndef VPX_VP8_DECODER_DBOOLHUFF_H_
12*fb1b10abSAndroid Build Coastguard Worker #define VPX_VP8_DECODER_DBOOLHUFF_H_
13*fb1b10abSAndroid Build Coastguard Worker
14*fb1b10abSAndroid Build Coastguard Worker #include <stddef.h>
15*fb1b10abSAndroid Build Coastguard Worker #include <limits.h>
16*fb1b10abSAndroid Build Coastguard Worker
17*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_config.h"
18*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/compiler_attributes.h"
19*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/mem.h"
20*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vp8dx.h"
21*fb1b10abSAndroid Build Coastguard Worker #include "vpx/vpx_integer.h"
22*fb1b10abSAndroid Build Coastguard Worker
23*fb1b10abSAndroid Build Coastguard Worker #ifdef __cplusplus
24*fb1b10abSAndroid Build Coastguard Worker extern "C" {
25*fb1b10abSAndroid Build Coastguard Worker #endif
26*fb1b10abSAndroid Build Coastguard Worker
27*fb1b10abSAndroid Build Coastguard Worker typedef size_t VP8_BD_VALUE;
28*fb1b10abSAndroid Build Coastguard Worker
29*fb1b10abSAndroid Build Coastguard Worker #define VP8_BD_VALUE_SIZE ((int)sizeof(VP8_BD_VALUE) * CHAR_BIT)
30*fb1b10abSAndroid Build Coastguard Worker
31*fb1b10abSAndroid Build Coastguard Worker /*This is meant to be a large, positive constant that can still be efficiently
32*fb1b10abSAndroid Build Coastguard Worker loaded as an immediate (on platforms like ARM, for example).
33*fb1b10abSAndroid Build Coastguard Worker Even relatively modest values like 100 would work fine.*/
34*fb1b10abSAndroid Build Coastguard Worker #define VP8_LOTS_OF_BITS (0x40000000)
35*fb1b10abSAndroid Build Coastguard Worker
36*fb1b10abSAndroid Build Coastguard Worker typedef struct {
37*fb1b10abSAndroid Build Coastguard Worker const unsigned char *user_buffer_end;
38*fb1b10abSAndroid Build Coastguard Worker const unsigned char *user_buffer;
39*fb1b10abSAndroid Build Coastguard Worker VP8_BD_VALUE value;
40*fb1b10abSAndroid Build Coastguard Worker int count;
41*fb1b10abSAndroid Build Coastguard Worker unsigned int range;
42*fb1b10abSAndroid Build Coastguard Worker vpx_decrypt_cb decrypt_cb;
43*fb1b10abSAndroid Build Coastguard Worker void *decrypt_state;
44*fb1b10abSAndroid Build Coastguard Worker } BOOL_DECODER;
45*fb1b10abSAndroid Build Coastguard Worker
46*fb1b10abSAndroid Build Coastguard Worker DECLARE_ALIGNED(16, extern const unsigned char, vp8_norm[256]);
47*fb1b10abSAndroid Build Coastguard Worker
48*fb1b10abSAndroid Build Coastguard Worker int vp8dx_start_decode(BOOL_DECODER *br, const unsigned char *source,
49*fb1b10abSAndroid Build Coastguard Worker unsigned int source_sz, vpx_decrypt_cb decrypt_cb,
50*fb1b10abSAndroid Build Coastguard Worker void *decrypt_state);
51*fb1b10abSAndroid Build Coastguard Worker
52*fb1b10abSAndroid Build Coastguard Worker void vp8dx_bool_decoder_fill(BOOL_DECODER *br);
53*fb1b10abSAndroid Build Coastguard Worker
vp8dx_decode_bool(BOOL_DECODER * br,int probability)54*fb1b10abSAndroid Build Coastguard Worker static VPX_NO_UNSIGNED_SHIFT_CHECK int vp8dx_decode_bool(BOOL_DECODER *br,
55*fb1b10abSAndroid Build Coastguard Worker int probability) {
56*fb1b10abSAndroid Build Coastguard Worker unsigned int bit = 0;
57*fb1b10abSAndroid Build Coastguard Worker VP8_BD_VALUE value;
58*fb1b10abSAndroid Build Coastguard Worker unsigned int split;
59*fb1b10abSAndroid Build Coastguard Worker VP8_BD_VALUE bigsplit;
60*fb1b10abSAndroid Build Coastguard Worker int count;
61*fb1b10abSAndroid Build Coastguard Worker unsigned int range;
62*fb1b10abSAndroid Build Coastguard Worker
63*fb1b10abSAndroid Build Coastguard Worker split = 1 + (((br->range - 1) * probability) >> 8);
64*fb1b10abSAndroid Build Coastguard Worker
65*fb1b10abSAndroid Build Coastguard Worker if (br->count < 0) vp8dx_bool_decoder_fill(br);
66*fb1b10abSAndroid Build Coastguard Worker
67*fb1b10abSAndroid Build Coastguard Worker value = br->value;
68*fb1b10abSAndroid Build Coastguard Worker count = br->count;
69*fb1b10abSAndroid Build Coastguard Worker
70*fb1b10abSAndroid Build Coastguard Worker bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8);
71*fb1b10abSAndroid Build Coastguard Worker
72*fb1b10abSAndroid Build Coastguard Worker range = split;
73*fb1b10abSAndroid Build Coastguard Worker
74*fb1b10abSAndroid Build Coastguard Worker if (value >= bigsplit) {
75*fb1b10abSAndroid Build Coastguard Worker range = br->range - split;
76*fb1b10abSAndroid Build Coastguard Worker value = value - bigsplit;
77*fb1b10abSAndroid Build Coastguard Worker bit = 1;
78*fb1b10abSAndroid Build Coastguard Worker }
79*fb1b10abSAndroid Build Coastguard Worker
80*fb1b10abSAndroid Build Coastguard Worker {
81*fb1b10abSAndroid Build Coastguard Worker const unsigned char shift = vp8_norm[(unsigned char)range];
82*fb1b10abSAndroid Build Coastguard Worker range <<= shift;
83*fb1b10abSAndroid Build Coastguard Worker value <<= shift;
84*fb1b10abSAndroid Build Coastguard Worker count -= shift;
85*fb1b10abSAndroid Build Coastguard Worker }
86*fb1b10abSAndroid Build Coastguard Worker br->value = value;
87*fb1b10abSAndroid Build Coastguard Worker br->count = count;
88*fb1b10abSAndroid Build Coastguard Worker br->range = range;
89*fb1b10abSAndroid Build Coastguard Worker
90*fb1b10abSAndroid Build Coastguard Worker return bit;
91*fb1b10abSAndroid Build Coastguard Worker }
92*fb1b10abSAndroid Build Coastguard Worker
vp8_decode_value(BOOL_DECODER * br,int bits)93*fb1b10abSAndroid Build Coastguard Worker static INLINE int vp8_decode_value(BOOL_DECODER *br, int bits) {
94*fb1b10abSAndroid Build Coastguard Worker int z = 0;
95*fb1b10abSAndroid Build Coastguard Worker int bit;
96*fb1b10abSAndroid Build Coastguard Worker
97*fb1b10abSAndroid Build Coastguard Worker for (bit = bits - 1; bit >= 0; bit--) {
98*fb1b10abSAndroid Build Coastguard Worker z |= (vp8dx_decode_bool(br, 0x80) << bit);
99*fb1b10abSAndroid Build Coastguard Worker }
100*fb1b10abSAndroid Build Coastguard Worker
101*fb1b10abSAndroid Build Coastguard Worker return z;
102*fb1b10abSAndroid Build Coastguard Worker }
103*fb1b10abSAndroid Build Coastguard Worker
vp8dx_bool_error(BOOL_DECODER * br)104*fb1b10abSAndroid Build Coastguard Worker static INLINE int vp8dx_bool_error(BOOL_DECODER *br) {
105*fb1b10abSAndroid Build Coastguard Worker /* Check if we have reached the end of the buffer.
106*fb1b10abSAndroid Build Coastguard Worker *
107*fb1b10abSAndroid Build Coastguard Worker * Variable 'count' stores the number of bits in the 'value' buffer, minus
108*fb1b10abSAndroid Build Coastguard Worker * 8. The top byte is part of the algorithm, and the remainder is buffered
109*fb1b10abSAndroid Build Coastguard Worker * to be shifted into it. So if count == 8, the top 16 bits of 'value' are
110*fb1b10abSAndroid Build Coastguard Worker * occupied, 8 for the algorithm and 8 in the buffer.
111*fb1b10abSAndroid Build Coastguard Worker *
112*fb1b10abSAndroid Build Coastguard Worker * When reading a byte from the user's buffer, count is filled with 8 and
113*fb1b10abSAndroid Build Coastguard Worker * one byte is filled into the value buffer. When we reach the end of the
114*fb1b10abSAndroid Build Coastguard Worker * data, count is additionally filled with VP8_LOTS_OF_BITS. So when
115*fb1b10abSAndroid Build Coastguard Worker * count == VP8_LOTS_OF_BITS - 1, the user's data has been exhausted.
116*fb1b10abSAndroid Build Coastguard Worker */
117*fb1b10abSAndroid Build Coastguard Worker if ((br->count > VP8_BD_VALUE_SIZE) && (br->count < VP8_LOTS_OF_BITS)) {
118*fb1b10abSAndroid Build Coastguard Worker /* We have tried to decode bits after the end of
119*fb1b10abSAndroid Build Coastguard Worker * stream was encountered.
120*fb1b10abSAndroid Build Coastguard Worker */
121*fb1b10abSAndroid Build Coastguard Worker return 1;
122*fb1b10abSAndroid Build Coastguard Worker }
123*fb1b10abSAndroid Build Coastguard Worker
124*fb1b10abSAndroid Build Coastguard Worker /* No error. */
125*fb1b10abSAndroid Build Coastguard Worker return 0;
126*fb1b10abSAndroid Build Coastguard Worker }
127*fb1b10abSAndroid Build Coastguard Worker
128*fb1b10abSAndroid Build Coastguard Worker #ifdef __cplusplus
129*fb1b10abSAndroid Build Coastguard Worker } // extern "C"
130*fb1b10abSAndroid Build Coastguard Worker #endif
131*fb1b10abSAndroid Build Coastguard Worker
132*fb1b10abSAndroid Build Coastguard Worker #endif // VPX_VP8_DECODER_DBOOLHUFF_H_
133