diff options
Diffstat (limited to 'vp9/decoder/vp9_dboolhuff.h')
-rw-r--r-- | vp9/decoder/vp9_dboolhuff.h | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/vp9/decoder/vp9_dboolhuff.h b/vp9/decoder/vp9_dboolhuff.h new file mode 100644 index 000000000..d46d81bb4 --- /dev/null +++ b/vp9/decoder/vp9_dboolhuff.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2010 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + +#ifndef DBOOLHUFF_H +#define DBOOLHUFF_H +#include <stddef.h> +#include <limits.h> +#include "vpx_ports/config.h" +#include "vpx_ports/mem.h" +#include "vpx/vpx_integer.h" + +typedef size_t VP9_BD_VALUE; + +# define VP9_BD_VALUE_SIZE ((int)sizeof(VP9_BD_VALUE)*CHAR_BIT) +/*This is meant to be a large, positive constant that can still be efficiently + loaded as an immediate (on platforms like ARM, for example). + Even relatively modest values like 100 would work fine.*/ +# define VP9_LOTS_OF_BITS (0x40000000) + +typedef struct { + const unsigned char *user_buffer_end; + const unsigned char *user_buffer; + VP9_BD_VALUE value; + int count; + unsigned int range; +} BOOL_DECODER; + +DECLARE_ALIGNED(16, extern const unsigned char, vp9_norm[256]); + +int vp9_start_decode(BOOL_DECODER *br, + const unsigned char *source, + unsigned int source_sz); + +void vp9_bool_decoder_fill(BOOL_DECODER *br); + +int vp9_decode_uniform(BOOL_DECODER *br, int n); +int vp9_decode_term_subexp(BOOL_DECODER *br, int k, int num_syms); +int vp9_inv_recenter_nonneg(int v, int m); + +/*The refill loop is used in several places, so define it in a macro to make + sure they're all consistent. + An inline function would be cleaner, but has a significant penalty, because + multiple BOOL_DECODER fields must be modified, and the compiler is not smart + enough to eliminate the stores to those fields and the subsequent reloads + from them when inlining the function.*/ +#define VP9DX_BOOL_DECODER_FILL(_count,_value,_bufptr,_bufend) \ + do \ + { \ + int shift = VP9_BD_VALUE_SIZE - 8 - ((_count) + 8); \ + int loop_end, x; \ + int bits_left = (int)(((_bufend)-(_bufptr))*CHAR_BIT); \ + \ + x = shift + CHAR_BIT - bits_left; \ + loop_end = 0; \ + if(x >= 0) \ + { \ + (_count) += VP9_LOTS_OF_BITS; \ + loop_end = x; \ + if(!bits_left) break; \ + } \ + while(shift >= loop_end) \ + { \ + (_count) += CHAR_BIT; \ + (_value) |= (VP9_BD_VALUE)*(_bufptr)++ << shift; \ + shift -= CHAR_BIT; \ + } \ + } \ + while(0) \ + + +static int decode_bool(BOOL_DECODER *br, int probability) { + unsigned int bit = 0; + VP9_BD_VALUE value; + unsigned int split; + VP9_BD_VALUE bigsplit; + int count; + unsigned int range; + + split = 1 + (((br->range - 1) * probability) >> 8); + + if (br->count < 0) + vp9_bool_decoder_fill(br); + + value = br->value; + count = br->count; + + bigsplit = (VP9_BD_VALUE)split << (VP9_BD_VALUE_SIZE - 8); + + range = split; + + if (value >= bigsplit) { + range = br->range - split; + value = value - bigsplit; + bit = 1; + } + + { + register unsigned int shift = vp9_norm[range]; + range <<= shift; + value <<= shift; + count -= shift; + } + br->value = value; + br->count = count; + br->range = range; + + return bit; +} + +static int decode_value(BOOL_DECODER *br, int bits) { + int z = 0; + int bit; + + for (bit = bits - 1; bit >= 0; bit--) { + z |= (decode_bool(br, 0x80) << bit); + } + + return z; +} + +static int bool_error(BOOL_DECODER *br) { + /* Check if we have reached the end of the buffer. + * + * Variable 'count' stores the number of bits in the 'value' buffer, minus + * 8. The top byte is part of the algorithm, and the remainder is buffered + * to be shifted into it. So if count == 8, the top 16 bits of 'value' are + * occupied, 8 for the algorithm and 8 in the buffer. + * + * When reading a byte from the user's buffer, count is filled with 8 and + * one byte is filled into the value buffer. When we reach the end of the + * data, count is additionally filled with VP9_LOTS_OF_BITS. So when + * count == VP9_LOTS_OF_BITS - 1, the user's data has been exhausted. + */ + if ((br->count > VP9_BD_VALUE_SIZE) && (br->count < VP9_LOTS_OF_BITS)) { + /* We have tried to decode bits after the end of + * stream was encountered. + */ + return 1; + } + + /* No error. */ + return 0; +} + +#endif |