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