/* getbits.c, bit level routines */ /* * tmndecode * Copyright (C) 1995 Telenor R&D * Karl Olav Lillevold * * based on mpeg2decode, (C) 1994, MPEG Software Simulation Group * and mpeg2play, (C) 1994 Stefan Eckart * * */ #include #include "config.h" #include "global.h" /* to mask the n least significant bits of an integer */ static unsigned int msk[33] = { 0x00000000,0x00000001,0x00000003,0x00000007, 0x0000000f,0x0000001f,0x0000003f,0x0000007f, 0x000000ff,0x000001ff,0x000003ff,0x000007ff, 0x00000fff,0x00001fff,0x00003fff,0x00007fff, 0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, 0x000fffff,0x001fffff,0x003fffff,0x007fffff, 0x00ffffff,0x01ffffff,0x03ffffff,0x07ffffff, 0x0fffffff,0x1fffffff,0x3fffffff,0x7fffffff, 0xffffffff }; /* initialize buffer, call once before first getbits or showbits */ void initbits() { ld->incnt = 0; ld->rdptr = ld->rdbfr + 2048; ld->bitcnt = 0; } void fillbfr() { int l; ld->inbfr[0] = ld->inbfr[8]; ld->inbfr[1] = ld->inbfr[9]; ld->inbfr[2] = ld->inbfr[10]; ld->inbfr[3] = ld->inbfr[11]; if (ld->rdptr>=ld->rdbfr+2048) { l = read(ld->infile,ld->rdbfr,2048); ld->rdptr = ld->rdbfr; if (l<2048) { if (l<0) l = 0; while (l<2048) /* Add recognizable sequence end code */ { ld->rdbfr[l++] = 0; ld->rdbfr[l++] = 0; ld->rdbfr[l++] = (1<<7) | (SEC<<2); } } } for (l=0; l<8; l++) ld->inbfr[l+4] = ld->rdptr[l]; ld->rdptr+= 8; ld->incnt+= 64; } /* return next n bits (right adjusted) without advancing */ unsigned int showbits(n) int n; { unsigned char *v; unsigned int b; int c; if (ld->incntinbfr + ((96 - ld->incnt)>>3); b = (v[0]<<24) | (v[1]<<16) | (v[2]<<8) | v[3]; c = ((ld->incnt-1) & 7) + 25; return (b>>(c-n)) & msk[n]; } /* return next bit (could be made faster than getbits(1)) */ unsigned int getbits1() { return getbits(1); } /* advance by n bits */ void flushbits(n) int n; { ld->bitcnt+= n; ld->incnt-= n; if (ld->incnt < 0) fillbfr(); } /* return next n bits (right adjusted) */ unsigned int getbits(n) int n; { unsigned int l; l = showbits(n); flushbits(n); return l; } /* for enhancement layer */ /* initialize buffer, call once before first getbits or showbits */ void en_initbits() { en_ld->incnt = 0; en_ld->rdptr = en_ld->rdbfr + 2048; en_ld->bitcnt = 0; } void en_fillbfr() { int l; en_ld->inbfr[0] = en_ld->inbfr[8]; en_ld->inbfr[1] = en_ld->inbfr[9]; en_ld->inbfr[2] = en_ld->inbfr[10]; en_ld->inbfr[3] = en_ld->inbfr[11]; if (en_ld->rdptr>=en_ld->rdbfr+2048) { l = read(en_ld->infile,en_ld->rdbfr,2048); en_ld->rdptr = en_ld->rdbfr; if (l<2048) { if (l < 0 ){ l = 0; printf("something wrong with enhancement file"); exit(-2); } while (l<2048) /* Add recognizable sequence end code */ { en_ld->rdbfr[l++] = 0; en_ld->rdbfr[l++] = 0; en_ld->rdbfr[l++] = (1<<7) | (SEC<<2); } } } for (l=0; l<8; l++) en_ld->inbfr[l+4] = en_ld->rdptr[l]; en_ld->rdptr+= 8; en_ld->incnt+= 64; } /* return next n bits (right adjusted) without advancing */ unsigned int en_showbits(n) int n; { unsigned char *v; unsigned int b; int c; if (en_ld->incntinbfr + ((96 - en_ld->incnt)>>3); b = (v[0]<<24) | (v[1]<<16) | (v[2]<<8) | v[3]; c = ((en_ld->incnt-1) & 7) + 25; return (b>>(c-n)) & msk[n]; } /* return next bit (could be made faster than getbits(1)) */ unsigned int en_getbits1() { return en_getbits(1); } /* advance by n bits */ void en_flushbits(n) int n; { en_ld->bitcnt+= n; en_ld->incnt-= n; if (en_ld->incnt < 0) en_fillbfr(); } /* return next n bits (right adjusted) */ unsigned int en_getbits(n) int n; { unsigned int l; l = en_showbits(n); en_flushbits(n); return l; }