#include #include #include #include #include #include "h261vlc.h" #include "bitio.h" #include "video_common.h" bit_io::bit_io() { valid_rbits = valid_wbits = 0; buf_rbytes = buf_wbytes = 0; total_rbytes = total_wbytes = 0; curr_rbyte = curr_wbyte = 0; read_buf = write_buf = 0; max_rbits = 0; max_wbytes = 0; } void bit_io::attach_rbuf(u_char *buf, int max_bits) { curr_rbyte = 0; valid_rbits = 0; buf_rbytes = 0; read_buf = buf; max_rbits = max_bits; } void bit_io::attach_wbuf(u_char *buf, int max_bytes) { curr_wbyte = 0; valid_wbits = 0; buf_wbytes = 0; write_buf = buf; max_wbytes = max_bytes; } void bit_io::print(void) { fprintf(stderr, "read: %d, write: %d rbyte: %d wbyte: %d valid_rbits: %d valid_wbits: %d\n", total_rbytes, total_wbytes, int(curr_rbyte), int(curr_wbyte), valid_rbits, valid_wbits); } int bit_io::GetRbufBits(void) { return max_rbits; } int bit_io::read_bit(void) throw (PicException_t) { int rc = 0, mask=0; if(!max_rbits) throw(PicException_t(READ_EXPT)); if(!valid_rbits) { curr_rbyte = read_buf[buf_rbytes++]; valid_rbits = 8; total_rbytes++; } rc = curr_rbyte; mask = 1 << (valid_rbits - 1); rc = rc & mask; rc = rc >> (valid_rbits - 1); valid_rbits--; max_rbits--; return rc; } int bit_io::read_bits(int len) { int rc = 0; for(int i=0; i < len; i++) rc = (rc << 1) | read_bit(); return rc; } int bit_io::write_flush(void) throw (PicException_t) { if(valid_wbits) { write_buf[buf_wbytes++] = curr_wbyte; if(buf_wbytes > max_wbytes) throw (PicException_t(WRITE_EXPT)); valid_wbits = 0; curr_wbyte = 0; } return 0; } int bit_io::GetBufWbytes(void) { return buf_wbytes; } int bit_io::wflush_bits(void) { int looptimes = (8 - valid_wbits)%8 ; for(int i=0; i < looptimes; i++) write_bit(0); return looptimes; } int bit_io::write_bit(int bitvalue) { u_char rc = bitvalue; rc = (rc << (8 - valid_wbits - 1)); /* Now write the bit */ curr_wbyte = curr_wbyte | rc; valid_wbits++; if(valid_wbits == 8) write_flush(); return 0; } int bit_io::write_bits(struct symbol_code& s, int terminate) { return write_bits(s.bitstring, s.codelen, terminate); } int bit_io::write_bits(u_char *bitstream, int numbits, int terminate) { u_char mask = 0; u_char rc = 0; int looptimes = numbits; if(terminate) looptimes = (8 - valid_wbits) % 8; for(int i=0; i < looptimes; i++) { /* Take bit out of bit stream */ mask = 1 << (7 - (i % 8)); rc = (bitstream[i/8] & mask) >> (7 - (i % 8)); write_bit(rc); } return 0; } void print_elem(tree_node *node) { printf("%d %d\n", node->huf.symbol, node->huf.prob); } int add_to_tree(tree_node *root, symbol_string& s) { tree_node *curr_node, *tmp; char *bit = s.string; char ctmp; curr_node = root; #ifdef DEBUG fprintf(stderr, "Adding %d\t%s\n", symbol, codestring); #endif while( (ctmp = *bit++)) { /* Till the end of the string */ if(ctmp == ' ') continue; if(ctmp != '0' && ctmp != '1') { #ifdef BOUNDS_CHECK bounds_error(__LINE__, __FILE__, __PRETTY_FUNCTION__); continue; #endif } if(ctmp == '1') { if(!curr_node->left){ tmp = new tree_node; curr_node->left = tmp; tmp->top = curr_node; } curr_node = curr_node->left; } if(ctmp == '0') { if(!curr_node->right){ tmp = new tree_node; curr_node->right = tmp; tmp->top = curr_node; } curr_node = curr_node->right; } } /* Now we are at the end of the line */ curr_node->huf.symbol = s.symbol; return 0; } int tree_read(bit_io *input, tree_node *root, int& symbol) { int curr_bit = 0; tree_node *curr_node = root; #ifdef BOUNDS_CHECK if(!curr_node) bounds_error(__LINE__, __FILE__, __PRETTY_FUNCTION__); if(!curr_node->left && !curr_node->right) bounds_error(__LINE__, __FILE__, __PRETTY_FUNCTION__); #endif while( (curr_bit = input->read_bit()) != -1) { if(curr_bit) { curr_node = curr_node->left; } else { curr_node = curr_node->right; } if(!curr_node) { #ifdef BOUNDS_CHECK bounds_error(__LINE__, __FILE__, __PRETTY_FUNCTION__); #endif return -1; } if(!curr_node->left && !curr_node->right) { symbol = curr_node->huf.symbol; return 0; } } return -1; }