bitwise.c 25 KB

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