| /* |
| * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license and patent |
| * grant that can be found in the LICENSE file in the root of the source |
| * tree. All contributing project authors may be found in the AUTHORS |
| * file in the root of the source tree. |
| */ |
| |
| |
| #include "dboolhuff.h" |
| #include "vpx_ports/mem.h" |
| #include "vpx_mem/vpx_mem.h" |
| |
| DECLARE_ALIGNED(16, const unsigned int, vp8dx_bitreader_norm[256]) = |
| { |
| 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
| 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
| }; |
| |
| |
| static void copy_in(BOOL_DECODER *br, unsigned int to_write) |
| { |
| if (to_write > br->user_buffer_sz) |
| to_write = br->user_buffer_sz; |
| |
| memcpy(br->write_ptr, br->user_buffer, to_write); |
| br->user_buffer += to_write; |
| br->user_buffer_sz -= to_write; |
| br->write_ptr = br_ptr_advance(br->write_ptr, to_write); |
| } |
| |
| int vp8dx_start_decode_c(BOOL_DECODER *br, const unsigned char *source, |
| unsigned int source_sz) |
| { |
| br->lowvalue = 0; |
| br->range = 255; |
| br->count = 0; |
| br->user_buffer = source; |
| br->user_buffer_sz = source_sz; |
| |
| if (source_sz && !source) |
| return 1; |
| |
| /* Allocate the ring buffer backing store with alignment equal to the |
| * buffer size*2 so that a single pointer can be used for wrapping rather |
| * than a pointer+offset. |
| */ |
| br->decode_buffer = vpx_memalign(VP8_BOOL_DECODER_SZ * 2, |
| VP8_BOOL_DECODER_SZ); |
| |
| if (!br->decode_buffer) |
| return 1; |
| |
| /* Populate the buffer */ |
| br->read_ptr = br->decode_buffer; |
| br->write_ptr = br->decode_buffer; |
| copy_in(br, VP8_BOOL_DECODER_SZ); |
| |
| /* Read the first byte */ |
| br->value = (*br->read_ptr++) << 8; |
| return 0; |
| } |
| |
| |
| void vp8dx_bool_decoder_fill_c(BOOL_DECODER *br) |
| { |
| int left, right; |
| |
| /* Find available room in the buffer */ |
| left = 0; |
| right = br->read_ptr - br->write_ptr; |
| |
| if (right < 0) |
| { |
| /* Read pointer is behind the write pointer. We can write from the |
| * write pointer to the end of the buffer. |
| */ |
| right = VP8_BOOL_DECODER_SZ - (br->write_ptr - br->decode_buffer); |
| left = br->read_ptr - br->decode_buffer; |
| } |
| |
| if (right + left < 128) |
| return; |
| |
| if (right) |
| copy_in(br, right); |
| |
| if (left) |
| { |
| br->write_ptr = br->decode_buffer; |
| copy_in(br, left); |
| } |
| |
| } |
| |
| |
| void vp8dx_stop_decode_c(BOOL_DECODER *bc) |
| { |
| vpx_free(bc->decode_buffer); |
| bc->decode_buffer = 0; |
| } |
| |
| #if 0 |
| /* |
| * Until optimized versions of these functions are available, we |
| * keep the implementation in the header to allow inlining. |
| * |
| * The RTCD-style invocations are still in place so this can |
| * be switched by just uncommenting these functions here and |
| * the DBOOLHUFF_INVOKE calls in the header. |
| */ |
| int vp8dx_decode_bool_c(BOOL_DECODER *br, int probability) |
| { |
| unsigned int bit=0; |
| unsigned int split; |
| unsigned int bigsplit; |
| register unsigned int range = br->range; |
| register unsigned int value = br->value; |
| |
| split = 1 + (((range-1) * probability) >> 8); |
| bigsplit = (split<<8); |
| |
| range = split; |
| if(value >= bigsplit) |
| { |
| range = br->range-split; |
| value = value-bigsplit; |
| bit = 1; |
| } |
| |
| /*if(range>=0x80) |
| { |
| br->value = value; |
| br->range = range; |
| return bit; |
| }*/ |
| |
| { |
| int count = br->count; |
| register unsigned int shift = vp8dx_bitreader_norm[range]; |
| range <<= shift; |
| value <<= shift; |
| count -= shift; |
| if(count <= 0) |
| { |
| value |= (*br->read_ptr) << (-count); |
| br->read_ptr = br_ptr_advance(br->read_ptr, 1); |
| count += 8 ; |
| } |
| br->count = count; |
| } |
| br->value = value; |
| br->range = range; |
| return bit; |
| } |
| |
| int vp8dx_decode_value_c(BOOL_DECODER *br, int bits) |
| { |
| int z = 0; |
| int bit; |
| for ( bit=bits-1; bit>=0; bit-- ) |
| { |
| z |= (vp8dx_decode_bool(br, 0x80)<<bit); |
| } |
| return z; |
| } |
| #endif |