bitwise.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
  4. * *
  5. * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
  6. * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  7. * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
  8. * *
  9. * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
  10. * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
  11. * *
  12. ********************************************************************
  13. function: packing variable sized words into an octet stream
  14. ********************************************************************/
  15. /* We're 'LSb' endian; if we write a word but read individual bits,
  16. then we'll read the lsb first */
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include "misc.h"
  20. #include "ogg.h"
  21. #include <stdio.h>
  22. #if !defined(ARM_LITTLE_ENDIAN) || defined(_V_BIT_TEST)
  23. static unsigned long mask[]=
  24. {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
  25. 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
  26. 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
  27. 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
  28. 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
  29. 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
  30. 0x3fffffff,0x7fffffff,0xffffffff };
  31. #endif
  32. #ifdef ARM_LITTLE_ENDIAN
  33. #ifdef DEBUGGING_BITWISE
  34. extern void oggpack_readinitARM(oggpack_buffer *b,ogg_reference *r);
  35. void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
  36. oggpack_readinitARM(b,r);
  37. //fprintf(stderr, "Init: buffer=(%d,%x,%d,%d) %08x%08x\n",
  38. // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
  39. // b->ptr[1], b->ptr[0]);
  40. //fflush(stderr);
  41. }
  42. extern long oggpack_lookARM(oggpack_buffer *b,int bits);
  43. long oggpack_look(oggpack_buffer *b,int bits){
  44. long l;
  45. //fprintf(stderr, "PreLook: buffer=(%x,%x,%x) %08x%08x (%d bits)\n",
  46. // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord,
  47. // b->ptr[1], b->ptr[0], bits);
  48. //fflush(stderr);
  49. l = oggpack_lookARM(b,bits);
  50. //fprintf(stderr, "Look: buffer=(%d,%x,%d,%d) %08x%08x (%d bits) (result=%x)\n",
  51. // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
  52. // b->ptr[1], b->ptr[0], bits, l);
  53. //fflush(stderr);
  54. return l;
  55. }
  56. extern void oggpack_advARM(oggpack_buffer *b,int bits);
  57. void oggpack_adv(oggpack_buffer *b,int bits){
  58. //fprintf(stderr, "Adv before: buffer=(%x,%x,%x) %08x%08x (%d bits)\n",
  59. // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord,
  60. // b->ptr[1], b->ptr[0],bits);
  61. //fflush(stderr);
  62. oggpack_advARM(b,bits);
  63. //fprintf(stderr, "Adv: buffer=(%d,%x,%d,%d) %08x%08x\n",
  64. // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
  65. // b->ptr[1], b->ptr[0]);
  66. //fflush(stderr);
  67. }
  68. extern long oggpack_readARM(oggpack_buffer *b,int bits);
  69. /* bits <= 32 */
  70. long oggpack_read(oggpack_buffer *b,int bits){
  71. long l;
  72. //fprintf(stderr, "PreRead: buffer=(%d,%x,%d,%d) %08x%08x (%d bits)\n",
  73. // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
  74. // b->ptr[1], b->ptr[0], bits);
  75. //fflush(stderr);
  76. l = oggpack_readARM(b,bits);
  77. //fprintf(stderr, "Read: buffer=(%d,%x,%d,%d) %08x%08x (%d bits) (result=%x)\n",
  78. // b->bitsLeftInSegment, b->ptr, b->bitsLeftInWord, b->count,
  79. // b->ptr[1], b->ptr[0], bits, l);
  80. //fflush(stderr);
  81. return l;
  82. }
  83. #endif
  84. int oggpack_eop(oggpack_buffer *b){
  85. int ret;
  86. if(b->bitsLeftInSegment<0)ret= -1;
  87. else ret = 0;
  88. //fprintf(stderr, "EOP %d\n", ret);
  89. //fflush(stderr);
  90. return ret;
  91. }
  92. long oggpack_bytes(oggpack_buffer *b){
  93. long ret;
  94. if(b->bitsLeftInSegment<0) ret = b->count+b->head->length;
  95. else ret = b->count + b->head->length - (b->bitsLeftInSegment)/8;
  96. //fprintf(stderr, "count=%d length=%d bitsLeftInSegment=%d\n",
  97. // b->count, b->head->length, b->bitsLeftInSegment);
  98. //fflush(stderr);
  99. return ret;
  100. }
  101. long oggpack_bits(oggpack_buffer *b){
  102. long ret;
  103. if(b->bitsLeftInSegment<0) ret=(b->count+b->head->length)*8;
  104. else ret = b->count*8 + b->head->length*8 - b->bitsLeftInSegment;
  105. //fprintf(stderr, "count=%d length=%d bitsLeftInSegment=%d\n",
  106. // b->count, b->head->length, b->bitsLeftInSegment);
  107. //fflush(stderr);
  108. return ret;
  109. }
  110. #else
  111. /* spans forward, skipping as many bytes as headend is negative; if
  112. headend is zero, simply finds next byte. If we're up to the end
  113. of the buffer, leaves headend at zero. If we've read past the end,
  114. halt the decode process. */
  115. static void _span(oggpack_buffer *b){
  116. while(b->headend-(b->headbit>>3)<1){
  117. b->headend-=b->headbit>>3;
  118. b->headbit&=0x7;
  119. if(b->head->next){
  120. b->count+=b->head->length;
  121. b->head=b->head->next;
  122. if(b->headend+b->head->length>0)
  123. b->headptr=b->head->buffer->data+b->head->begin-b->headend;
  124. b->headend+=b->head->length;
  125. }else{
  126. /* we've either met the end of decode, or gone past it. halt
  127. only if we're past */
  128. if(b->headend*8<b->headbit)
  129. /* read has fallen off the end */
  130. b->headend=-1;
  131. break;
  132. }
  133. }
  134. }
  135. void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
  136. memset(b,0,sizeof(*b));
  137. b->tail=b->head=r;
  138. b->count=0;
  139. b->headptr=b->head->buffer->data+b->head->begin;
  140. b->headend=b->head->length;
  141. _span(b);
  142. //fprintf(stderr,
  143. // "Init: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x\n",
  144. // b->headbit, b->headptr, b->headend, b->count,
  145. // b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
  146. // b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0]);
  147. //fflush(stderr);
  148. }
  149. #define _lookspan() while(!end){\
  150. head=head->next;\
  151. if(!head) return -1;\
  152. ptr=head->buffer->data + head->begin;\
  153. end=head->length;\
  154. }
  155. /* Read in bits without advancing the bitptr; bits <= 32 */
  156. long oggpack_look(oggpack_buffer *b,int bits){
  157. unsigned long m=mask[bits];
  158. unsigned long ret;
  159. int BITS = bits;
  160. bits+=b->headbit;
  161. if(bits >= b->headend<<3){
  162. int end=b->headend;
  163. unsigned char *ptr=b->headptr;
  164. ogg_reference *head=b->head;
  165. if(end<0)return -1;
  166. if(bits){
  167. _lookspan();
  168. ret=*ptr++>>b->headbit;
  169. if(bits>8){
  170. --end;
  171. _lookspan();
  172. ret|=*ptr++<<(8-b->headbit);
  173. if(bits>16){
  174. --end;
  175. _lookspan();
  176. ret|=*ptr++<<(16-b->headbit);
  177. if(bits>24){
  178. --end;
  179. _lookspan();
  180. ret|=*ptr++<<(24-b->headbit);
  181. if(bits>32 && b->headbit){
  182. --end;
  183. _lookspan();
  184. ret|=*ptr<<(32-b->headbit);
  185. }
  186. }
  187. }
  188. }
  189. }
  190. }else{
  191. /* make this a switch jump-table */
  192. ret=b->headptr[0]>>b->headbit;
  193. if(bits>8){
  194. ret|=b->headptr[1]<<(8-b->headbit);
  195. if(bits>16){
  196. ret|=b->headptr[2]<<(16-b->headbit);
  197. if(bits>24){
  198. ret|=b->headptr[3]<<(24-b->headbit);
  199. if(bits>32 && b->headbit)
  200. ret|=b->headptr[4]<<(32-b->headbit);
  201. }
  202. }
  203. }
  204. }
  205. ret&=m;
  206. //fprintf(stderr,
  207. // "Look: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x (%d bits) return=%x\n",
  208. // b->headbit, b->headptr, b->headend, b->count,
  209. // b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
  210. // b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
  211. // BITS, ret);
  212. //fflush(stderr);
  213. return ret;
  214. }
  215. /* limited to 32 at a time */
  216. void oggpack_adv(oggpack_buffer *b,int bits){
  217. int BITS=bits;
  218. bits+=b->headbit;
  219. b->headbit=bits&7;
  220. b->headend-=(bits>>3);
  221. b->headptr+=(bits>>3);
  222. if(b->headend<1)_span(b);
  223. //fprintf(stderr, "Adv: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x (%d bits)\n",
  224. // b->headbit, b->headptr, b->headend,b->count,
  225. // b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
  226. // b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
  227. // BITS);
  228. //fflush(stderr);
  229. }
  230. int oggpack_eop(oggpack_buffer *b){
  231. int ret;
  232. if(b->headend<0)ret= -1;
  233. else ret = 0;
  234. //fprintf(stderr, "EOP %d\n", ret);
  235. //fflush(stderr);
  236. return ret;
  237. }
  238. long oggpack_bytes(oggpack_buffer *b){
  239. long ret;
  240. if(b->headend<0) ret = b->count+b->head->length;
  241. ret = b->count + b->head->length-b->headend + (b->headbit+7)/8;
  242. //fprintf(stderr, "Bytes: buffer=(%d,%x,%d,%d) %02x%02x%02x%02x%02x%02x%02x%02x (%d bytes)\n",
  243. // b->headbit, b->headptr, b->headend, b->count,
  244. // b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
  245. // b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
  246. // ret);
  247. //fflush(stderr);
  248. return ret;
  249. }
  250. long oggpack_bits(oggpack_buffer *b){
  251. long ret;
  252. if(b->headend<0) ret = (b->count+b->head->length)*8;
  253. else ret = (b->count + b->head->length-b->headend)*8 + b->headbit;
  254. //fprintf(stderr, "Bits: buffer=(%x,%x,%x) %02x%02x%02x%02x%02x%02x%02x%02x (%d bits)\n",
  255. // b->headbit, b->headptr, b->headend,
  256. // b->headptr[7], b->headptr[6], b->headptr[5], b->headptr[4],
  257. // b->headptr[3], b->headptr[2], b->headptr[1], b->headptr[0],
  258. // ret);
  259. //fflush(stderr);
  260. return ret;
  261. }
  262. /* bits <= 32 */
  263. long oggpack_read(oggpack_buffer *b,int bits){
  264. long ret=oggpack_look(b,bits);
  265. oggpack_adv(b,bits);
  266. return(ret);
  267. }
  268. #endif
  269. /* Self test of the bitwise routines; everything else is based on
  270. them, so they damned well better be solid. */
  271. #ifdef _V_BIT_TEST
  272. #include <string.h>
  273. #include <stdlib.h>
  274. #include <stdio.h>
  275. #include "framing.c"
  276. static int ilog(unsigned long v){
  277. int ret=0;
  278. while(v){
  279. ret++;
  280. v>>=1;
  281. }
  282. return(ret);
  283. }
  284. oggpack_buffer r;
  285. oggpack_buffer o;
  286. ogg_buffer_state *bs;
  287. ogg_reference *or;
  288. #define TESTWORDS 256
  289. void report(char *in){
  290. fprintf(stderr,"%s",in);
  291. exit(1);
  292. }
  293. int getbyte(ogg_reference *or,int position){
  294. while(or && position>=or->length){
  295. position-=or->length;
  296. or=or->next;
  297. if(or==NULL){
  298. fprintf(stderr,"\n\tERROR: getbyte ran off end of buffer.\n");
  299. exit(1);
  300. }
  301. }
  302. if((position+or->begin)&1)
  303. return (or->buffer->data[(position+or->begin)>>1])&0xff;
  304. else
  305. return (or->buffer->data[(position+or->begin)>>1]>>8)&0xff;
  306. }
  307. void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){
  308. long i,bitcount=0;
  309. ogg_reference *or=ogg_buffer_alloc(bs,64);
  310. for(i=0;i<compsize;i++)
  311. or->buffer->data[i]= comp[i];
  312. or->length=i;
  313. oggpack_readinit(&r,or);
  314. for(i=0;i<vals;i++){
  315. unsigned long test;
  316. int tbit=bits?bits:ilog(b[i]);
  317. if((test=oggpack_look(&r,tbit))==0xffffffff)
  318. report("out of data!\n");
  319. if(test!=(b[i]&mask[tbit])){
  320. fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
  321. report("looked at incorrect value!\n");
  322. }
  323. if((test=oggpack_read(&r,tbit))==0xffffffff){
  324. report("premature end of data when reading!\n");
  325. }
  326. if(test!=(b[i]&mask[tbit])){
  327. fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test);
  328. report("read incorrect value!\n");
  329. }
  330. bitcount+=tbit;
  331. if(bitcount!=oggpack_bits(&r))
  332. report("wrong number of bits while reading!\n");
  333. if((bitcount+7)/8!=oggpack_bytes(&r))
  334. report("wrong number of bytes while reading!\n");
  335. }
  336. if(oggpack_bytes(&r)!=(bitcount+7)/8){
  337. fprintf(stderr, "%d vs %d\n", oggpack_bytes(&r), (bitcount+7)/8);
  338. report("leftover bytes after read!\n");
  339. }
  340. ogg_buffer_release(or);
  341. }
  342. void _end_verify(int count){
  343. int i;
  344. /* are the proper number of bits left over? */
  345. int leftover=count*8-oggpack_bits(&o);
  346. if(leftover>7)
  347. report("\nERROR: too many bits reported left over.\n");
  348. /* does reading to exactly byte alignment *not* trip EOF? */
  349. if(oggpack_read(&o,leftover)==-1)
  350. report("\nERROR: read to but not past exact end tripped EOF.\n");
  351. if(oggpack_bits(&o)!=count*8)
  352. report("\nERROR: read to but not past exact end reported bad bitcount.\n");
  353. /* does EOF trip properly after a single additional bit? */
  354. if(oggpack_read(&o,1)!=-1)
  355. report("\nERROR: read past exact end did not trip EOF.\n");
  356. if(oggpack_bits(&o)!=count*8)
  357. report("\nERROR: read past exact end reported bad bitcount.\n");
  358. /* does EOF stay set over additional bit reads? */
  359. for(i=0;i<=32;i++){
  360. if(oggpack_read(&o,i)!=-1)
  361. report("\nERROR: EOF did not stay set on stream.\n");
  362. if(oggpack_bits(&o)!=count*8)
  363. report("\nERROR: read past exact end reported bad bitcount.\n");
  364. }
  365. }
  366. void _end_verify2(int count){
  367. int i;
  368. /* are the proper number of bits left over? */
  369. int leftover=count*8-oggpack_bits(&o);
  370. if(leftover>7)
  371. report("\nERROR: too many bits reported left over.\n");
  372. /* does reading to exactly byte alignment *not* trip EOF? */
  373. oggpack_adv(&o,leftover);
  374. #ifdef ARM_LITTLE_ENDIAN
  375. if(o.bitsLeftInSegment!=0)
  376. #else
  377. if(o.headend!=0)
  378. #endif
  379. report("\nERROR: read to but not past exact end tripped EOF.\n");
  380. if(oggpack_bits(&o)!=count*8)
  381. report("\nERROR: read to but not past exact end reported bad bitcount.\n");
  382. /* does EOF trip properly after a single additional bit? */
  383. oggpack_adv(&o,1);
  384. #ifdef ARM_LITTLE_ENDIAN
  385. if(o.bitsLeftInSegment>=0)
  386. #else
  387. if(o.headend>=0)
  388. #endif
  389. report("\nERROR: read past exact end did not trip EOF.\n");
  390. if(oggpack_bits(&o)!=count*8)
  391. report("\nERROR: read past exact end reported bad bitcount.\n");
  392. /* does EOF stay set over additional bit reads? */
  393. for(i=0;i<=32;i++){
  394. oggpack_adv(&o,i);
  395. #ifdef ARM_LITTLE_ENDIAN
  396. if(o.bitsLeftInSegment>=0)
  397. #else
  398. if(o.headend>=0)
  399. #endif
  400. report("\nERROR: EOF did not stay set on stream.\n");
  401. if(oggpack_bits(&o)!=count*8)
  402. report("\nERROR: read past exact end reported bad bitcount.\n");
  403. }
  404. }
  405. long ogg_buffer_length(ogg_reference *or){
  406. int count=0;
  407. while(or){
  408. count+=or->length;
  409. or=or->next;
  410. }
  411. return count;
  412. }
  413. ogg_reference *ogg_buffer_extend(ogg_reference *or,long bytes){
  414. if(or){
  415. while(or->next){
  416. or=or->next;
  417. }
  418. or->next=ogg_buffer_alloc(or->buffer->ptr.owner,bytes);
  419. return(or->next);
  420. }
  421. return 0;
  422. }
  423. void ogg_buffer_posttruncate(ogg_reference *or,long pos){
  424. /* walk to the point where we want to begin truncate */
  425. while(or && pos>or->length){
  426. pos-=or->length;
  427. or=or->next;
  428. }
  429. if(or){
  430. ogg_buffer_release(or->next);
  431. or->next=0;
  432. or->length=pos;
  433. }
  434. }
  435. int main(void){
  436. long i;
  437. static unsigned long testbuffer1[]=
  438. {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7,
  439. 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4};
  440. int test1size=43;
  441. static unsigned long testbuffer2[]=
  442. {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212,
  443. 1233432,534,5,346435231,14436467,7869299,76326614,167548585,
  444. 85525151,0,12321,1,349528352};
  445. int test2size=21;
  446. static unsigned long testbuffer3[]=
  447. {1,0,14,0,1,0,12,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1,
  448. 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1};
  449. int test3size=56;
  450. static unsigned long large[]=
  451. {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212,
  452. 1233432,534,5,2146435231,14436467,7869299,76326614,167548585,
  453. 85525151,0,12321,1,2146528352};
  454. int onesize=33;
  455. static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40,
  456. 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172,
  457. 223,4};
  458. int twosize=6;
  459. static int two[6]={61,255,255,251,231,29};
  460. int threesize=54;
  461. static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254,
  462. 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83,
  463. 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10,
  464. 100,52,4,14,18,86,77,1};
  465. int foursize=38;
  466. static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72,
  467. 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169,
  468. 28,2,133,0,1};
  469. int fivesize=45;
  470. static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62,
  471. 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169,
  472. 84,75,159,2,1,0,132,192,8,0,0,18,22};
  473. int sixsize=7;
  474. static int six[7]={17,177,170,242,169,19,148};
  475. /* Test read/write together */
  476. /* Later we test against pregenerated bitstreams */
  477. bs=ogg_buffer_create();
  478. fprintf(stderr,"\nSmall preclipped packing (LSb): ");
  479. cliptest(testbuffer1,test1size,0,one,onesize);
  480. fprintf(stderr,"ok.");
  481. fprintf(stderr,"\nNull bit call (LSb): ");
  482. cliptest(testbuffer3,test3size,0,two,twosize);
  483. fprintf(stderr,"ok.");
  484. fprintf(stderr,"\nLarge preclipped packing (LSb): ");
  485. cliptest(testbuffer2,test2size,0,three,threesize);
  486. fprintf(stderr,"ok.");
  487. fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
  488. or=ogg_buffer_alloc(bs,128);
  489. for(i=0;i<test2size;i++){
  490. or->buffer->data[i*4] = large[i]&0xff;
  491. or->buffer->data[i*4+1] = (large[i]>>8)&0xff;
  492. or->buffer->data[i*4+2] = (large[i]>>16)&0xff;
  493. or->buffer->data[i*4+3] = (large[i]>>24)&0xff;
  494. }
  495. or->length=test2size*4;
  496. oggpack_readinit(&r,or);
  497. for(i=0;i<test2size;i++){
  498. unsigned long test;
  499. if((test=oggpack_look(&r,32))==0xffffffffUL)report("out of data. failed!");
  500. if(test!=large[i]){
  501. fprintf(stderr,"%ld != %ld (%lx!=%lx):",test,large[i],
  502. test,large[i]);
  503. report("read incorrect value!\n");
  504. }
  505. oggpack_adv(&r,32);
  506. }
  507. ogg_buffer_release(or);
  508. if(oggpack_bytes(&r)!=test2size*4){
  509. fprintf(stderr, "%d vs %d\n", oggpack_bytes(&r), test2size*4);
  510. report("leftover bytes after read!\n");
  511. }
  512. fprintf(stderr,"ok.");
  513. fprintf(stderr,"\nSmall unclipped packing (LSb): ");
  514. cliptest(testbuffer1,test1size,7,four,foursize);
  515. fprintf(stderr,"ok.");
  516. fprintf(stderr,"\nLarge unclipped packing (LSb): ");
  517. cliptest(testbuffer2,test2size,17,five,fivesize);
  518. fprintf(stderr,"ok.");
  519. fprintf(stderr,"\nSingle bit unclipped packing (LSb): ");
  520. cliptest(testbuffer3,test3size,1,six,sixsize);
  521. fprintf(stderr,"ok.");
  522. fprintf(stderr,"\nTesting read past end (LSb): ");
  523. {
  524. unsigned char dda[]={0,0,0,0};
  525. ogg_buffer lob={dda,8,0,{0}};
  526. ogg_reference lor={&lob,0,8,0};
  527. oggpack_readinit(&r,&lor);
  528. for(i=0;i<64;i++){
  529. if(oggpack_read(&r,1)<0){
  530. fprintf(stderr,"failed; got -1 prematurely.\n");
  531. exit(1);
  532. }
  533. }
  534. if(oggpack_look(&r,1)!=-1 ||
  535. oggpack_read(&r,1)!=-1){
  536. fprintf(stderr,"failed; read past end without -1.\n");
  537. exit(1);
  538. }
  539. }
  540. {
  541. unsigned char dda[]={0,0,0,0};
  542. ogg_buffer lob={dda,8,0,{0}};
  543. ogg_reference lor={&lob,0,8,0};
  544. unsigned long test;
  545. oggpack_readinit(&r,&lor);
  546. if((test=oggpack_read(&r,30))==0xffffffffUL ||
  547. (test=oggpack_read(&r,16))==0xffffffffUL){
  548. fprintf(stderr,"failed 2; got -1 prematurely.\n");
  549. exit(1);
  550. }
  551. if((test=oggpack_look(&r,18))==0xffffffffUL){
  552. fprintf(stderr,"failed 3; got -1 prematurely.\n");
  553. exit(1);
  554. }
  555. if((test=oggpack_look(&r,19))!=0xffffffffUL){
  556. fprintf(stderr,"failed; read past end without -1.\n");
  557. exit(1);
  558. }
  559. if((test=oggpack_look(&r,32))!=0xffffffffUL){
  560. fprintf(stderr,"failed; read past end without -1.\n");
  561. exit(1);
  562. }
  563. }
  564. fprintf(stderr,"ok.\n");
  565. /* now the scary shit: randomized testing */
  566. for(i=0;i<10000;i++){
  567. long j,count=0,count2=0,bitcount=0;
  568. unsigned long values[TESTWORDS];
  569. int len[TESTWORDS];
  570. unsigned char flat[4*TESTWORDS]; /* max possible needed size */
  571. memset(flat,0,sizeof(flat));
  572. fprintf(stderr,"\rRandomized testing (LSb)... (%ld) ",10000-i);
  573. /* generate a list of words and lengths */
  574. /* write the required number of bits out to packbuffer */
  575. {
  576. long word=0;
  577. long bit=0;
  578. int k;
  579. for(j=0;j<TESTWORDS;j++){
  580. values[j]=rand();
  581. len[j]=(rand()%33);
  582. for(k=0;k<len[j];k++){
  583. flat[word] |= ((values[j]>>k)&0x1)<<bit;
  584. bit++;
  585. bitcount++;
  586. if(bit>7){
  587. bit=0;
  588. word++;
  589. }
  590. }
  591. }
  592. }
  593. count2=(bitcount+7)>>3;
  594. /* construct random-length buffer chain from flat vector; random
  595. byte starting offset within the length of the vector */
  596. {
  597. ogg_reference *or=NULL,*orl=NULL;
  598. long pos=0;
  599. /* build buffer chain */
  600. while(count2){
  601. int ilen=(rand()%32),k;
  602. int ibegin=(rand()%32);
  603. if(ilen>count2)ilen=count2;
  604. if(or)
  605. orl=ogg_buffer_extend(orl,64);
  606. else
  607. or=orl=ogg_buffer_alloc(bs,64);
  608. orl->length=ilen;
  609. orl->begin=ibegin;
  610. for(k=0;k<ilen;k++)
  611. orl->buffer->data[ibegin++]= flat[pos++];
  612. count2-=ilen;
  613. }
  614. if(ogg_buffer_length(or)!=(bitcount+7)/8){
  615. fprintf(stderr,"\nERROR: buffer length incorrect after build.\n");
  616. exit(1);
  617. }
  618. {
  619. int begin=0; //=(rand()%TESTWORDS);
  620. int ilen=(rand()%(TESTWORDS-begin));
  621. int bitoffset,bitcount=0;
  622. unsigned long temp;
  623. for(j=0;j<begin;j++)
  624. bitcount+=len[j];
  625. or=ogg_buffer_pretruncate(or,bitcount/8);
  626. bitoffset=bitcount%=8;
  627. for(;j<begin+ilen;j++)
  628. bitcount+=len[j];
  629. ogg_buffer_posttruncate(or,((bitcount+7)/8));
  630. if((count=ogg_buffer_length(or))!=(bitcount+7)/8){
  631. fprintf(stderr,"\nERROR: buffer length incorrect after truncate.\n");
  632. exit(1);
  633. }
  634. oggpack_readinit(&o,or);
  635. /* verify bit count */
  636. if(oggpack_bits(&o)!=0){
  637. fprintf(stderr,"\nERROR: Read bitcounter not zero!\n");
  638. exit(1);
  639. }
  640. if(oggpack_bytes(&o)!=0){
  641. fprintf(stderr,"\nERROR: Read bytecounter not zero!\n");
  642. exit(1);
  643. }
  644. bitcount=bitoffset;
  645. oggpack_read(&o,bitoffset);
  646. /* read and compare to original list */
  647. for(j=begin;j<begin+ilen;j++){
  648. temp=oggpack_read(&o,len[j]);
  649. if(temp==0xffffffffUL){
  650. fprintf(stderr,"\nERROR: End of stream too soon! word: %ld,%d\n",
  651. j-begin,ilen);
  652. exit(1);
  653. }
  654. if(temp!=(values[j]&mask[len[j]])){
  655. fprintf(stderr,"\nERROR: Incorrect read %lx != %lx, word %ld, len %d\n"
  656. ,
  657. values[j]&mask[len[j]],temp,j-begin,len[j]);
  658. exit(1);
  659. }
  660. bitcount+=len[j];
  661. if(oggpack_bits(&o)!=bitcount){
  662. fprintf(stderr,"\nERROR: Read bitcounter %d != %ld!\n",
  663. bitcount,oggpack_bits(&o));
  664. exit(1);
  665. }
  666. if(oggpack_bytes(&o)!=(bitcount+7)/8){
  667. fprintf(stderr,"\nERROR: Read bytecounter %d != %ld!\n",
  668. (bitcount+7)/8,oggpack_bytes(&o));
  669. exit(1);
  670. }
  671. }
  672. _end_verify(count);
  673. /* look/adv version */
  674. oggpack_readinit(&o,or);
  675. bitcount=bitoffset;
  676. oggpack_adv(&o,bitoffset);
  677. /* read and compare to original list */
  678. for(j=begin;j<begin+ilen;j++){
  679. temp=oggpack_look(&o,len[j]);
  680. if(temp==0xffffffffUL){
  681. fprintf(stderr,"\nERROR: End of stream too soon! word: %ld\n",
  682. j-begin);
  683. exit(1);
  684. }
  685. if(temp!=(values[j]&mask[len[j]])){
  686. fprintf(stderr,"\nERROR: Incorrect look %lx != %lx, word %ld, len %d\n"
  687. ,
  688. values[j]&mask[len[j]],temp,j-begin,len[j]);
  689. exit(1);
  690. }
  691. oggpack_adv(&o,len[j]);
  692. bitcount+=len[j];
  693. if(oggpack_bits(&o)!=bitcount){
  694. fprintf(stderr,"\nERROR: Look/Adv bitcounter %d != %ld!\n",
  695. bitcount,oggpack_bits(&o));
  696. exit(1);
  697. }
  698. if(oggpack_bytes(&o)!=(bitcount+7)/8){
  699. fprintf(stderr,"\nERROR: Look/Adv bytecounter %d != %ld!\n",
  700. (bitcount+7)/8,oggpack_bytes(&o));
  701. exit(1);
  702. }
  703. }
  704. _end_verify2(count);
  705. }
  706. ogg_buffer_release(or);
  707. }
  708. }
  709. fprintf(stderr,"\rRandomized testing (LSb)... ok. \n");
  710. return(0);
  711. }
  712. #ifdef _WIN32_WCE
  713. int WinMain(void){
  714. return main();
  715. }
  716. #endif
  717. #endif