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