xref: /aosp_15_r20/external/libvpx/vp8/decoder/dboolhuff.h (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
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