?? bitstr.c
字號:
/****************************************************************************//* * bitstr.c -- BitStream files handling * * Author : St閜hane TAVENARD * * (C) Copyright 1997-1998 St閜hane TAVENARD * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//****************************************************************************/#include "defs.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include "bitstr.h"/****************************************************************************//* * Default file I/O functions. */static long def_open(char *stream_name, long buffer_size, long *stream_size){ FILE *file_ptr; file_ptr = fopen(stream_name, "rb"); if ((file_ptr) && (buffer_size > 0)) setvbuf(file_ptr, NULL, _IOFBF, buffer_size); *stream_size = 0; if (file_ptr) { if (!fseek(file_ptr, 0, SEEK_END)) { *stream_size = ftell(file_ptr); fseek(file_ptr, 0, SEEK_SET); } } return((long) file_ptr);}/****************************************************************************/static void def_close( long handle ){ if (handle) fclose((FILE *) handle);}/****************************************************************************/static long def_read(long handle, void *buffer, long num_bytes){ long read_size = -1; if (handle) read_size = fread(buffer, 1, num_bytes, (FILE *) handle); return(read_size);}/****************************************************************************/static int def_seek(long handle, long abs_byte_seek_pos){ int err = 0; if (handle) err = fseek((FILE *) handle, abs_byte_seek_pos, SEEK_SET); return(err);}/****************************************************************************//* * End of default file I/O functions. */void BSTR_close(BITSTREAM *bitstream){ if (bitstream) { if (bitstream->buffer) //ffree(bitstream->buffer); free(bitstream->buffer); if (bitstream->file_handle) { if (bitstream->baccess.close) bitstream->baccess.close(bitstream->file_handle); } free(bitstream); }}/****************************************************************************//* * Open a BitStream for read * Inputs: * bs_access = specify how to access to the bitstream (functions) * if NULL, use standard file i/o * filename = name of the bitstream * buffer_size = # of bytes read for each access */BITSTREAM *BSTR_open(BITSTREAM_ACCESS *bs_access, char *filename, long buffer_size){ BITSTREAM *bs; bs = (BITSTREAM *) malloc(sizeof(BITSTREAM)); if (!bs) return NULL; memset(bs, 0, sizeof(BITSTREAM)); if (bs_access) { bs->baccess = *bs_access; } else { bs->baccess.open = def_open; bs->baccess.close = def_close; bs->baccess.read = def_read; bs->baccess.seek = def_seek; } // Buffer size must be 4-bytes aligned buffer_size &= ~3; bs->buffer = malloc(buffer_size); //bs->buffer = fmalloc(buffer_size); if (!bs->buffer) { BSTR_close(bs); return(NULL); } bs->buffer_size = buffer_size; if (!bs->baccess.open) { BSTR_close(bs); return(NULL); } bs->file_handle = bs->baccess.open(filename, buffer_size, &bs->bitstream_size); if (!bs->file_handle) { BSTR_close(bs); return(NULL); } bs->buffer_ptr = bs->buffer; // #10 bs->buffer_len = 0; // #10 bs->buffer_pos = 0; // #10 return(bs);}/****************************************************************************/static int fill_buffer(BITSTREAM *bitstream){#ifdef BSTR_MSBF bitstream->buffer[0] = 0;#else bitstream->buffer[1] = bitstream->buffer[2] = bitstream->buffer[3] = 0;#endif if (bitstream->end_of_stream) return 1; if (!bitstream->baccess.read) return 1; bitstream->remain_bytes = bitstream->baccess.read( bitstream->file_handle, bitstream->buffer, bitstream->buffer_size ); bitstream->buffer_len = bitstream->remain_bytes; // #10 bitstream->buffer_pos += (long)bitstream->buffer_ptr - (long)bitstream->buffer; // #10 bitstream->buffer_ptr = bitstream->buffer; bitstream->cache_size = 0; if (bitstream->remain_bytes <= 0) { bitstream->end_of_stream = 1; return(1); /* empty */ } else if (bitstream->remain_bytes < 4) { bitstream->remain_bytes = 4; } return(0);}/****************************************************************************/#ifdef BSTR_MSBF#define FILL_CACHE(b) { \ if (b->remain_bytes <= 0) \ fill_buffer(b); \ b->remain_bytes -= 4; \ b->bit_cache = *b->buffer_ptr++; \}#else#define FILL_CACHE(b) { \ if (b->remain_bytes <= 0) \ fill_buffer(b); \ b->remain_bytes -= 4; \ b->bit_cache = (((unsigned long)b->buffer_ptr[0])<<24) | \ (((unsigned long)b->buffer_ptr[1])<<16)| \ (((unsigned long)b->buffer_ptr[2])<<8) | \ ((unsigned long)b->buffer_ptr[3]); b->buffer_ptr+=4; \}#endif/****************************************************************************/int BSTR_seek(BITSTREAM *bitstream, long seek_byte_pos){ int err; // Optimize seek if inside current buffer long offset_pos = seek_byte_pos - bitstream->buffer_pos; if (bitstream->buffer_len > 0) { if ((offset_pos >= 0) && (offset_pos < bitstream->buffer_len)) { // Use current buffer long remain = offset_pos & 3; // Remainder offset_pos &= ~3; // align to 32 bit bitstream->remain_bytes = bitstream->buffer_len - offset_pos;#ifdef BSTR_MSBF bitstream->buffer_ptr = bitstream->buffer + (offset_pos>>2);#else bitstream->buffer_ptr = bitstream->buffer + offset_pos;#endif bitstream->cache_size = 0; bitstream->bits = 0; FILL_CACHE(bitstream); bitstream->cache_size = 32; // Skip remainder while(remain--) BSTR_read_byte(bitstream); return(0); } } if (bitstream->baccess.seek) { err = bitstream->baccess.seek(bitstream->file_handle, seek_byte_pos); if (err) return(err); } bitstream->remain_bytes = 0; bitstream->buffer_ptr = bitstream->buffer; bitstream->end_of_stream = 0; bitstream->cache_size = 0; bitstream->bits = 0; bitstream->buffer_len = 0; // #10 bitstream->buffer_pos = seek_byte_pos; // #10 return(0);}/****************************************************************************/long BSTR_pos(BITSTREAM *bitstream){ return(bitstream->buffer_pos + (long)bitstream->buffer_ptr - (long)bitstream->buffer - (bitstream->cache_size >> 3));}/****************************************************************************/unsigned long BSTR_read_byte(BITSTREAM *b){ if (b->cache_size < 8) { FILL_CACHE(b); b->cache_size = 32; } if (b->cache_size & 7) { // Not aligned b->bit_cache <<= b->cache_size & 7; b->cache_size &= ~7; } b->bits = b->bit_cache >> 24; b->bit_cache <<= 8; b->cache_size -= 8; return(b->bits);}/****************************************************************************/unsigned int BSTR_read_bytes(BITSTREAM *b, unsigned int count, char *buffer){ if (count == 0) return 0; if (b->cache_size & 7) { // Not aligned b->bit_cache <<= b->cache_size & 7; b->cache_size &= ~7; } while ((b->cache_size > 0) && (count-- > 0 )) { *buffer++ = b->bit_cache >> 24; b->bit_cache <<= 8; b->cache_size -= 8; } while (count > 3) { int to_fill; if (b->remain_bytes <= 0) { if (fill_buffer(b)) return 0; } to_fill = count & ~3; // Important 4-bytes aligned // Note: b->remain_bytes is always 4-bytes aligned if (to_fill > b->remain_bytes) to_fill = b->remain_bytes; memcpy(buffer, b->buffer_ptr, to_fill); count -= to_fill; buffer += to_fill; b->remain_bytes -= to_fill;#ifdef BSTR_MSBF // This is a INT32 pointer here. b->buffer_ptr += to_fill>>2;#else b->buffer_ptr += to_fill;#endif } // Not 4 bytes aligned -> use cached read while (count > 0) { *buffer++ = BSTR_read_byte(b); count--; } b->bits = (unsigned int)*(buffer-1); return(1);}/****************************************************************************/unsigned long BSTR_read_bit_cache(BITSTREAM *b){ unsigned long bits; FILL_CACHE(b); b->cache_size = 31; bits = (b->bit_cache & 0x80000000) ? 1 : 0; b->bit_cache <<= 1; return(bits);}/****************************************************************************/unsigned long BSTR_read_bits_cache(BITSTREAM *b, unsigned int count){ unsigned long bits; bits = b->bit_cache >> (32 - count); count -= b->cache_size; FILL_CACHE(b); b->cache_size = 32 - count; bits |= b->bit_cache >> (32 - count); b->bit_cache <<= count; return(bits);}/****************************************************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -