michael@0: /* michael@0: * Copyright (c) 2010 The WebM project authors. All Rights Reserved. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license michael@0: * that can be found in the LICENSE file in the root of the source michael@0: * tree. An additional intellectual property rights grant can be found michael@0: * in the file PATENTS. All contributing project authors may michael@0: * be found in the AUTHORS file in the root of the source tree. michael@0: */ michael@0: michael@0: #ifndef VP9_DECODER_VP9_DBOOLHUFF_H_ michael@0: #define VP9_DECODER_VP9_DBOOLHUFF_H_ michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "./vpx_config.h" michael@0: #include "vpx_ports/mem.h" michael@0: #include "vpx/vpx_integer.h" michael@0: michael@0: typedef size_t VP9_BD_VALUE; michael@0: michael@0: #define BD_VALUE_SIZE ((int)sizeof(VP9_BD_VALUE)*CHAR_BIT) michael@0: michael@0: typedef struct { michael@0: const uint8_t *buffer_end; michael@0: const uint8_t *buffer; michael@0: VP9_BD_VALUE value; michael@0: int count; michael@0: unsigned int range; michael@0: } vp9_reader; michael@0: michael@0: DECLARE_ALIGNED(16, extern const uint8_t, vp9_norm[256]); michael@0: michael@0: int vp9_reader_init(vp9_reader *r, const uint8_t *buffer, size_t size); michael@0: michael@0: void vp9_reader_fill(vp9_reader *r); michael@0: michael@0: const uint8_t *vp9_reader_find_end(vp9_reader *r); michael@0: michael@0: static int vp9_read(vp9_reader *br, int probability) { michael@0: unsigned int bit = 0; michael@0: VP9_BD_VALUE value; michael@0: VP9_BD_VALUE bigsplit; michael@0: int count; michael@0: unsigned int range; michael@0: unsigned int split = ((br->range * probability) + (256 - probability)) >> 8; michael@0: michael@0: if (br->count < 0) michael@0: vp9_reader_fill(br); michael@0: michael@0: value = br->value; michael@0: count = br->count; michael@0: michael@0: bigsplit = (VP9_BD_VALUE)split << (BD_VALUE_SIZE - 8); michael@0: michael@0: range = split; michael@0: michael@0: if (value >= bigsplit) { michael@0: range = br->range - split; michael@0: value = value - bigsplit; michael@0: bit = 1; michael@0: } michael@0: michael@0: { michael@0: register unsigned int shift = vp9_norm[range]; michael@0: range <<= shift; michael@0: value <<= shift; michael@0: count -= shift; michael@0: } michael@0: br->value = value; michael@0: br->count = count; michael@0: br->range = range; michael@0: michael@0: return bit; michael@0: } michael@0: michael@0: static int vp9_read_bit(vp9_reader *r) { michael@0: return vp9_read(r, 128); // vp9_prob_half michael@0: } michael@0: michael@0: static int vp9_read_literal(vp9_reader *br, int bits) { michael@0: int z = 0, bit; michael@0: michael@0: for (bit = bits - 1; bit >= 0; bit--) michael@0: z |= vp9_read_bit(br) << bit; michael@0: michael@0: return z; michael@0: } michael@0: michael@0: int vp9_reader_has_error(vp9_reader *r); michael@0: michael@0: #endif // VP9_DECODER_VP9_DBOOLHUFF_H_