123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /*
- ** nsvbs.h - NSV basic inline bitstream classes
- **
- ** Copyright (C) 2001-2002 Nullsoft, Inc.
- ** Confidential Subject to NDA
- **
- ** Note: these bitstream classes encode/decode everything in LSB.
- ** bits are stored from the lowest bit to the highest bit.
- ** putbits(4,0xE) will result in getbits(1)=0, getbits(1)=1,
- ** getbits(1)=1, getbits(1)=1
- ** or of course, getbits(4) == 0xE :)
- */
- #ifndef _NSVBS_H_
- #define _NSVBS_H_
- #include <stdlib.h>
- #include <memory.h>
- #include <bfc/platform/types.h>
- #include "../nu/GrowBuf.h"
- class nsv_OutBS
- {
- public:
- nsv_OutBS() { m_used = 0; m_curb=0; }
- ~nsv_OutBS() { }
- void putbits(int nbits, unsigned int value)
- {
- while (nbits-- > 0)
- {
- m_curb|=(value&1)<<(m_used&7);
- if (!((++m_used)&7))
- {
- m_bits.add(&m_curb,1);
- m_curb=0;
- }
- value>>=1;
- }
- }
- // lets you put in any amount of data, but does not preserve endianness.
- void putdata(int nbits, void *data)
- {
- unsigned char *c=(unsigned char *)data;
- if (!(m_used&7) && nbits >= 8)
- {
- m_bits.add(c,nbits/8);
- c+=nbits/8;
- m_used+=nbits&~7;
- nbits&=7;
- }
- while (nbits > 0)
- {
- int tb=nbits;
- if (tb > 8) tb=8;
- putbits(tb,*c++);
- nbits-=tb;
- }
- }
- int getlen() { return m_used; } // in bits
- void *get(int *len) // len is in bytes, forces to byte aligned.
- {
- if (m_used&7)
- {
- m_bits.add(&m_curb,1);
- m_used=(m_used+7)&~7;
- m_curb=0;
- }
- *len=m_used/8;
- return m_bits.get();
- }
- void clear()
- {
- m_used=0;
- m_curb=0;
- m_bits.resize(0);
- }
- private:
- GrowBuf m_bits;
- int m_used; // bits
- unsigned char m_curb;
- };
- class nsv_InBS {
- public:
- nsv_InBS() { m_bitpos=0; m_eof=0; }
- ~nsv_InBS() { }
- void clear()
- {
- m_eof=0;
- m_bitpos=0;
- m_bits.resize(0);
- }
- void add(void *data, int len)
- {
- m_bits.add(data,len);
- m_eof=0;
- }
- void addbyte(unsigned char byte)
- {
- add(&byte,1);
- }
- void addint(unsigned int dword)
- {
- addbyte(dword&0xff);
- addbyte((dword>>8)&0xff);
- addbyte((dword>>16)&0xff);
- addbyte((dword>>24)&0xff);
- }
-
- void compact()
- {
- size_t bytepos=m_bitpos/8;
- if (bytepos)
- {
- unsigned char *t=(unsigned char *)m_bits.get();
- size_t l=m_bits.getlen()-bytepos;
- memcpy(t,t+bytepos,l);
- m_bits.resize(l);
- m_bitpos&=7;
- }
- m_eof=0;
- }
- void seek(ptrdiff_t nbits)
- {
- if (nbits < 0 && ((size_t)(-nbits)) > m_bitpos)
- m_bitpos=0;
- else
- m_bitpos+=nbits;
- m_eof=m_bits.getlen()*8 < m_bitpos;
- }
- void rewind() { m_bitpos=0; m_eof=0; }
- int eof() { return m_eof; }
- size_t avail() { if (m_eof) return 0; return m_bits.getlen()*8 - m_bitpos; }
- unsigned int getbits(size_t nbits)
- {
- unsigned int ret=0;
- if (!nbits) return ret;
- unsigned char *t=(unsigned char *)m_bits.get();
- if (!t || m_bits.getlen()*8 < m_bitpos+nbits) m_eof=1;
- else
- {
- t+=m_bitpos/8;
- for (size_t sh = 0; sh != nbits; sh ++)
- {
- ret|=((*t>>(m_bitpos&7))&1) << sh;
- if (!((++m_bitpos)&7)) t++;
- }
- }
- return ret;
- }
- int getdata(size_t nbits, void *data)
- {
- unsigned char *t=(unsigned char *)data;
- if (m_bits.getlen()*8 < m_bitpos+nbits) return 1;
- if (!(m_bitpos&7) && nbits >= 8)
- {
- char *bitptr=(char*)m_bits.get();
- bitptr+=(m_bitpos/8);
- memcpy(t,bitptr,nbits/8);
- m_bitpos+=nbits&~7;
- t+=nbits/8;
- nbits&=7;
- }
- while (nbits > 0)
- {
- size_t nb=nbits;
- if (nb > 8) nb=8;
- *t++=getbits(nb);
- nbits-=nb;
- }
- return 0;
- }
- void *getcurbyteptr()
- {
- char *t=(char*)m_bits.get();
- return (void *)(t+(m_bitpos/8));
- }
- private:
- GrowBuf m_bits;
- size_t m_bitpos;
- int m_eof;
- };
- #endif//_NSVBS_H_
|