nsvbs.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. ** nsvbs.h - NSV basic inline bitstream classes
  3. **
  4. ** Copyright (C) 2001-2002 Nullsoft, Inc.
  5. ** Confidential Subject to NDA
  6. **
  7. ** Note: these bitstream classes encode/decode everything in LSB.
  8. ** bits are stored from the lowest bit to the highest bit.
  9. ** putbits(4,0xE) will result in getbits(1)=0, getbits(1)=1,
  10. ** getbits(1)=1, getbits(1)=1
  11. ** or of course, getbits(4) == 0xE :)
  12. */
  13. #ifndef _NSVBS_H_
  14. #define _NSVBS_H_
  15. #include <stdlib.h>
  16. #include <memory.h>
  17. #include <bfc/platform/types.h>
  18. #include "../nu/GrowBuf.h"
  19. class nsv_OutBS
  20. {
  21. public:
  22. nsv_OutBS() { m_used = 0; m_curb=0; }
  23. ~nsv_OutBS() { }
  24. void putbits(int nbits, unsigned int value)
  25. {
  26. while (nbits-- > 0)
  27. {
  28. m_curb|=(value&1)<<(m_used&7);
  29. if (!((++m_used)&7))
  30. {
  31. m_bits.add(&m_curb,1);
  32. m_curb=0;
  33. }
  34. value>>=1;
  35. }
  36. }
  37. // lets you put in any amount of data, but does not preserve endianness.
  38. void putdata(int nbits, void *data)
  39. {
  40. unsigned char *c=(unsigned char *)data;
  41. if (!(m_used&7) && nbits >= 8)
  42. {
  43. m_bits.add(c,nbits/8);
  44. c+=nbits/8;
  45. m_used+=nbits&~7;
  46. nbits&=7;
  47. }
  48. while (nbits > 0)
  49. {
  50. int tb=nbits;
  51. if (tb > 8) tb=8;
  52. putbits(tb,*c++);
  53. nbits-=tb;
  54. }
  55. }
  56. int getlen() { return m_used; } // in bits
  57. void *get(int *len) // len is in bytes, forces to byte aligned.
  58. {
  59. if (m_used&7)
  60. {
  61. m_bits.add(&m_curb,1);
  62. m_used=(m_used+7)&~7;
  63. m_curb=0;
  64. }
  65. *len=m_used/8;
  66. return m_bits.get();
  67. }
  68. void clear()
  69. {
  70. m_used=0;
  71. m_curb=0;
  72. m_bits.resize(0);
  73. }
  74. private:
  75. GrowBuf m_bits;
  76. int m_used; // bits
  77. unsigned char m_curb;
  78. };
  79. class nsv_InBS {
  80. public:
  81. nsv_InBS() { m_bitpos=0; m_eof=0; }
  82. ~nsv_InBS() { }
  83. void clear()
  84. {
  85. m_eof=0;
  86. m_bitpos=0;
  87. m_bits.resize(0);
  88. }
  89. void add(void *data, int len)
  90. {
  91. m_bits.add(data,len);
  92. m_eof=0;
  93. }
  94. void addbyte(unsigned char byte)
  95. {
  96. add(&byte,1);
  97. }
  98. void addint(unsigned int dword)
  99. {
  100. addbyte(dword&0xff);
  101. addbyte((dword>>8)&0xff);
  102. addbyte((dword>>16)&0xff);
  103. addbyte((dword>>24)&0xff);
  104. }
  105. void compact()
  106. {
  107. size_t bytepos=m_bitpos/8;
  108. if (bytepos)
  109. {
  110. unsigned char *t=(unsigned char *)m_bits.get();
  111. size_t l=m_bits.getlen()-bytepos;
  112. memcpy(t,t+bytepos,l);
  113. m_bits.resize(l);
  114. m_bitpos&=7;
  115. }
  116. m_eof=0;
  117. }
  118. void seek(ptrdiff_t nbits)
  119. {
  120. if (nbits < 0 && ((size_t)(-nbits)) > m_bitpos)
  121. m_bitpos=0;
  122. else
  123. m_bitpos+=nbits;
  124. m_eof=m_bits.getlen()*8 < m_bitpos;
  125. }
  126. void rewind() { m_bitpos=0; m_eof=0; }
  127. int eof() { return m_eof; }
  128. size_t avail() { if (m_eof) return 0; return m_bits.getlen()*8 - m_bitpos; }
  129. unsigned int getbits(size_t nbits)
  130. {
  131. unsigned int ret=0;
  132. if (!nbits) return ret;
  133. unsigned char *t=(unsigned char *)m_bits.get();
  134. if (!t || m_bits.getlen()*8 < m_bitpos+nbits) m_eof=1;
  135. else
  136. {
  137. t+=m_bitpos/8;
  138. for (size_t sh = 0; sh != nbits; sh ++)
  139. {
  140. ret|=((*t>>(m_bitpos&7))&1) << sh;
  141. if (!((++m_bitpos)&7)) t++;
  142. }
  143. }
  144. return ret;
  145. }
  146. int getdata(size_t nbits, void *data)
  147. {
  148. unsigned char *t=(unsigned char *)data;
  149. if (m_bits.getlen()*8 < m_bitpos+nbits) return 1;
  150. if (!(m_bitpos&7) && nbits >= 8)
  151. {
  152. char *bitptr=(char*)m_bits.get();
  153. bitptr+=(m_bitpos/8);
  154. memcpy(t,bitptr,nbits/8);
  155. m_bitpos+=nbits&~7;
  156. t+=nbits/8;
  157. nbits&=7;
  158. }
  159. while (nbits > 0)
  160. {
  161. size_t nb=nbits;
  162. if (nb > 8) nb=8;
  163. *t++=getbits(nb);
  164. nbits-=nb;
  165. }
  166. return 0;
  167. }
  168. void *getcurbyteptr()
  169. {
  170. char *t=(char*)m_bits.get();
  171. return (void *)(t+(m_bitpos/8));
  172. }
  173. private:
  174. GrowBuf m_bits;
  175. size_t m_bitpos;
  176. int m_eof;
  177. };
  178. #endif//_NSVBS_H_