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 static int vp8dx_decode_bool(BOOL_DECODER *br, int probability) { 54 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 split = 1 + (((br->range - 1) * probability) >> 8); 62 63 if (br->count < 0) vp8dx_bool_decoder_fill(br); 64 65 value = br->value; 66 count = br->count; 67 68 bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8); 69 70 range = split; 71 72 if (value >= bigsplit) { 73 range = br->range - split; 74 value = value - bigsplit; 75 bit = 1; 76 } 77 78 { 79 register int shift = vp8_norm[range]; 80 range <<= shift; 81 value <<= shift; 82 count -= shift; 83 } 84 br->value = value; 85 br->count = count; 86 br->range = range; 87 88 return bit; 89 } 90 91 static INLINE int vp8_decode_value(BOOL_DECODER *br, int bits) { 92 int z = 0; 93 int bit; 94 95 for (bit = bits - 1; bit >= 0; bit--) { 96 z |= (vp8dx_decode_bool(br, 0x80) << bit); 97 } 98 99 return z; 100 } 101 102 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 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 return 1; 120 } 121 122 /* No error. */ 123 return 0; 124 } 125 126 #ifdef __cplusplus 127 } // extern "C" 128 #endif 129 130 #endif // VP8_DECODER_DBOOLHUFF_H_ 131