📄 bitstr.c
字号:
#ifdef PPC // #9 // We always need a M68k Hook function free( bs ); return NULL;#else bs->baccess.h_Entry = (HOOKFUNC)def_baccess;#endif }#else if( bs_access ) { // #3 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; }#endif // Buffer size must be 4-bytes aligned buffer_size &= ~3;#ifdef PPC // #9 // Mark as non cachable memory area because shared by M68k & PPC// bs->buffer = PPCAllocVec( buffer_size, MEMF_PUBLIC | MEMF_CLEAR | MEMF_NOCACHESYNCPPC | MEMF_NOCACHESYNCM68K ); // #11 Old bs->buffer = PPCAllocVec( buffer_size, MEMF_PUBLIC | MEMF_CLEAR ); // #11 Cached// bs->buffer = malloc( buffer_size );#else bs->buffer = malloc( buffer_size );#endif if( !bs->buffer ) { BSTR_close( bs ); return NULL; } bs->buffer_size = buffer_size;#ifdef HOOKS // #8 { BSTR_ACCESS_PARAM param; param.func = BSTR_FUNC_OPEN; param.data.open.stream_name = filename; param.data.open.buffer_size = buffer_size; param.data.open.stream_size = 0;#ifdef PPC // #9 Begin bs->file_handle = ppc_call_hook( bs, NULL, ¶m );#else// bs->file_handle = CallHookPkt( &bs->baccess, NULL, ¶m ); bs->file_handle = ((BSTR_HOOK_FUNC)bs->baccess.h_Entry)( &bs->baccess, NULL, ¶m );#endif // #9 End bs->bitstream_size = param.data.open.stream_size; }#else if( !bs->baccess.open ) { // #3 BSTR_close( bs ); return NULL; } bs->file_handle = bs->baccess.open( filename, buffer_size, &bs->bitstream_size );#endif if( !bs->file_handle ) { BSTR_close( bs ); return NULL; }// (void)BSTR_seek( bs, 0 ); 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; // #3#ifdef HOOKS // #8 { BSTR_ACCESS_PARAM param; param.func = BSTR_FUNC_READ; param.data.read.buffer = bitstream->buffer; param.data.read.num_bytes = bitstream->buffer_size;#ifdef PPC // #9 Begin PPCCacheFlush( bitstream->buffer, bitstream->buffer_size ); // #11 bitstream->remain_bytes = ppc_call_hook( bitstream, (APTR)bitstream->file_handle, ¶m );#else// bitstream->remain_bytes = CallHookPkt( &bitstream->baccess, (APTR)bitstream->file_handle, ¶m ); bitstream->remain_bytes = ((BSTR_HOOK_FUNC)bitstream->baccess.h_Entry)( &bitstream->baccess, (APTR)bitstream->file_handle, ¶m );#endif // #9 End }#else if( !bitstream->baccess.read ) return 1; // #3 bitstream->remain_bytes = bitstream->baccess.read( bitstream->file_handle, bitstream->buffer, bitstream->buffer_size ); // #3#endif 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;} /* fill_buffer */#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;\ }#endifint BSTR_seek( BITSTREAM *bitstream, long seek_byte_pos ){ int err; // #10 Begin // 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-- ) (void)BSTR_read_byte( bitstream ); return 0; } } // #10 End#ifdef HOOKS // #8 { BSTR_ACCESS_PARAM param; param.func = BSTR_FUNC_SEEK; param.data.seek.abs_byte_seek_pos = seek_byte_pos;#ifdef PPC // #9 Begin err = ppc_call_hook( bitstream, (APTR)bitstream->file_handle, ¶m );#else// err = (int)CallHookPkt( &bitstream->baccess, (APTR)bitstream->file_handle, ¶m ); err = (int)((BSTR_HOOK_FUNC)bitstream->baccess.h_Entry)( &bitstream->baccess, (APTR)bitstream->file_handle, ¶m );#endif // #9 End if( err ) return err; }#else if( bitstream->baccess.seek ) { err = bitstream->baccess.seek( bitstream->file_handle, seek_byte_pos ); if( err ) return err; // #7 }#endif 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;}/* #10 Begin */long BSTR_pos( BITSTREAM *bitstream ) { return bitstream->buffer_pos + (long)bitstream->buffer_ptr - (long)bitstream->buffer - (bitstream->cache_size >> 3);}/* #10 End */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 ) { register 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 b->buffer_ptr += to_fill>>2; // This is a INT32 pointer here.#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 ){ register 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 ){ register 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 + -